【React】propsのchildrenの基本的な使い方と実例(再利用性の高い部品作成方法)
Reactでコンポーネントを他のコンポーネントに渡せるpropsのchildrenの使い方を紹介します。
childrenを上手に使うことで、再利用性の高いコンポーネントを作成することができます。
childrenの基本的な使い方
他のコンポーネントをラップするコンポーネント(親)
import ChildComp from "./components/ChildComp";
import Container from "./components/Container";
const profile = [
{ name: "yamada", age: 78, country: "KOREA" },
{ name: "suzuki", age: 45, country: "USA" },
];
const Func = () => {
return (
<div>
<Container title="Childrenについて" >
{'children'}
<ChildComp {...profile[0]} />
<ChildComp {...profile[1]} />
</Container>
</div>
);
};
export default Func;
このように、コンポーネントの中にコンポーネントを入れることで、
propsと一緒にコンポーネントもpropsとして渡すことができます。
オブジェクトの配列にすることで、いろいろなデータを出力することが可能になります。
また、childrenは属性として設定することもできます。
const profile = [
{ name: "yamada", age: 78, country: "KOREA" },
{ name: "suzuki", age: 45, country: "USA" },
];
const Func = () => {
return (
<div>
<Container
title="Childrenについて"
children={
[(<ChildComp key={profile[0].name} {...profile[0]} />), (<ChildComp key={profile[1].name} {...profile[1]} />)]
}
></Container>
</div>
);
};
export default Func;
その場合、コンポーネントChildCompもJavaScriptのオブジェクトのため、上のようにして渡すことができます。
ただし、この場合はkey属性でユニークな値を指定する必要があります。(指定しないとエラーになります)
よって、上のようにユニークな値のkeyを指定します。
const Container = ({ title, children }) => {
console.log(children);
return (
<div className="container">
<h3>{title}</h3>
{children}
</div>
);
};
export default Container;
上のように、コンポーネントは、childrenの場所の引数で渡ってくるので、
{}で使うことができます。
childrenとしてラップされる側のコンポーネント(子)
const ChildComp = ({ name, age, country }) => {
return (
<div>
<h3>Name: {name}</h3>
<p>Age: {age} </p>
<p>Country: {country} </p>
</div>
);
};
export default ChildComp;
こちらは通常と同じです。
渡すコンポーネントの順番を指定する方法
ラップする側の親コンポーネント
import ChildComp from "./components/ChildComp";
import Container from "./components/Container";
const profile = [
{ name: "yamada", age: 78, country: "KOREA" },
{ name: "suzuki", age: 45, country: "USA" },
];
const Func = () => {
return (
<div>
<Container
title="Childrenについて"
children={[
<ChildComp key={profile[0].name} {...profile[0]} />,
<ChildComp key={profile[1].name} {...profile[1]} />,
]}
zero={<ChildComp key={profile[0].name} {...profile[0]} />}
first={<ChildComp key={profile[1].name} {...profile[1]} />}
></Container>
</div>
);
};
export default Func;
コンポーネントの順番を制御したい場合があります。
そのようなときは、上のように、それぞれのコンポーネントにそれぞれの属性をつけることで、可能になります。
ラップされる側の子コンポーネント
const Container = ({ title, children, zero, first }) => {
console.log(children);
return (
<div className="container">
<h3>{title}</h3>
{children}
{first}
{zero}
</div>
);
};
export default Container;
上のようにすることで、{zero}と{first}の順番を入れ替えたりすることで表示させるコンポーネントの順番を制御することができます。
よくある実例-再利用可能なカードコンポーネント
ラップする側の親コンポーネント
import "./card.css";
const Card = ({ children, className, onClick }) => {
return (
<article className={`card ${className}`} onClick={onClick}>
{children}
</article>
);
};
export default Card;
上のように、childrenのとかに、classNameを設定しておくと、たとえばaboutページとprofileページで同じカードを使うけど、クラス名だけを変更して再利用可能なコンポーネントとして利用することができます。
また、onClickはない場合は渡ってこないだけなので、onClickがある場合でもない場合上の書き方で問題ありません。
ラップされる側の子コンポーネント
import Card from "../../components/Card";
const data = [
{id: 1, icon: <Icon1/>, title: 'タイトル1', desc: 'desc1'},
{id: 2, icon: <Icon2/>, title: 'タイトル2', desc: 'desc2'},
{id: 3, icon: <Icon3/>, title: 'タイトル3', desc: 'desc3'}
]
const About = () => {
return (
<section id="about">
<div className="container about__container">
<h2>About Me</h2>
<div className="about__cards">
{data.map((item) => (
<Card key={item.id} className="about__card">
<span className="about__card-icon">{item.icon}</span>
<h5>{item.title}</h5>
<small>{item.desc}</small>
</Card>
))}
</div>
<p>
ここに文章
</p>
<a href={CV} download className="btn primary">
ダウンロード
</a>
</div>
</section>
);
};
export default About;
上のようにCardコンポーネント内で記述されたものがchildrenとして渡されます。
また、CardコンポーネントにclassNameをつけることで、静的な書き方であっても当然propsとしてclassNameが渡されます。
あとは、他のコンポーネントでも同じように、Cardコンポーネント内の記述とclassNameと、必要に応じてonClickを設定してあげれば、
再利用可能なカードコンポーネントになります。