もくじ
propsの流れ
親要素からpropsを渡して子要素で使用するのが多くの使用例かと思います。
ただ、受け取ったpropsをさらに子要素に渡したいというときもありますよね。ネストした中でコンポーネントを作成して使う場合など。
ここで画像のような例を見ていきましょう。
index.js
(画像では”もと”と表記)が親要素、赤色のコンポーネントPetsGroup
が子要素となり、親要素から子要素へpropsを渡します。
propsの使い方
props自体の受取り方、使い方を説明すると以下のようになります。
<PetsGroup title="ペット1" link="/hogehoge" />
この場合、props名はtitle
link
、propsの中身がそれぞれ" "
の中になります。
const PetsGroup = (title, link) => { return ( <h1>{title}<h1> <a href={link}>リンク</a> )}
引数に受け取ったprops名を指定することによってpropsを受け取ることができます。そして戻り値の中でprops名を中かっこで指定すると表示したり使用することができます。
(本題)親子の要素をまたぐコンポーネント
ここで本題です。
画像のように、親要素から受け取ったpropsを、赤色のPetsGroup
を通って、さらに子要素となる緑色のPets
へ渡したいときに{children}
を使用します。
const pet1 = [ { name: "ぽち", category: "dog", }, ] <PetsGroup title="ペット1" link="/hogehoge"> <Pets contents={pet1}/> </PetsGroup>
const PetsGroup = ({title, link, children}) => { return( <> <h1>{title}</h1> {children} <a href={link}>リンク</a> </> ) }
子要素のなかで引数でchildren
を受け取り、戻り値で{children}
とすると、この{children}
の箇所に親要素で挟んだコンポーネント<Pets>
をそのまま受け取ることができます。
そしてネストされた子要素の引数に親要素から渡されたpropsを指定することで直接propsを受け取ることができます。
- ネストされた子要素
親要素の<Pets contents={pet1}/>
で渡されたpropscontents
を引数にすることで使用できます。
この具体例ではcontents
はオブジェクトなのでmapを使用して中身を取り出しています。
const Pets = ({contents}) => { return( <ul> {contents.map((item) => ( <li> <div> <p>名前:{item.name}</p> <p>種類:{item.category}</p> </div> </li> ))} </ul> ) }
流れを図解化
実際のコード
実際のコードにはcssも書いているので読みにくい箇所もあるかもしれませんが、是非ご参考にしてください。
import React from 'react' import {PetsGroup} from './PetsGroup' import {Pets} from './Pets' export const Children = () => { const pet1 = [ { name: "ぽち", category: "dog", }, { name: "ぴょん", category: "rabbit", }, ] const pet2 = [ { name: "たま", category: "cat", } ] return ( <> <PetsGroup title="ペット1" link="/hogehoge"> <Pets contents={pet1}/> </PetsGroup> <PetsGroup title="ペット2" link="/hogehoge"> <Pets contents={pet2}/> </PetsGroup> </> ) }
import React from 'react' import styled from 'styled-components' export const PetsGroup = ({title, link, children}) => { return( <Box> <H1>{title}</H1> {children} <Link href={link}>詳細を見る</Link> </Box> ) } const Box = styled.div` width: 400px; margin: 3em 0; padding: 1rem; font-weight: bold; color: #6091d3; border: solid 3px #6091d3; border-radius: 10px; ` const H1 = styled.h1` text-align: center; ` const Link = styled.a` padding: 1rem; `
import React from 'react' import styled from 'styled-components' export const Pets = ({contents}) => { return( <Ul> {contents.map((item) => ( <List> <div> <Name>名前:{item.name}</Name> <Category>種類:{item.category}</Category> </div> </List> ))} </Ul> ) } const Ul = styled.ul` list-style: none; position: relative; padding: 0; margin: 0; ` const List = styled.li` padding: 7px; margin-bottom: 2rem; border-left: solid 5px #5c9ee7; background: #f1f8ff; color: #5c9ee7; font-weight: bold; -webkit-box-shadow:1px 1px 2px rgba(0, 0, 0, 0.1) ; -moz-box-shadow:1px 1px 2px rgba(0, 0, 0, 0.1) ; box-shadow:1px 1px 2px rgba(0, 0, 0, 0.1) ; ` const Name = styled.p` margin-bottom: 0; ` const Category = styled(Name)``
複雑な構造をわかりやすく
{children}
を使用すれば、複雑な構造でもコンポーネント化して他人がコードを見たときにもわかりやすいコードになります。
コンポーネントをネストする際{children}
が使える時は存分に使っていきましょう。存在をお忘れなく!