【React】{children}でコンポーネントを受け渡す

f:id:bonoponz:20200623215241p:plain

もくじ

propsの流れ

親要素からpropsを渡して子要素で使用するのが多くの使用例かと思います。

ただ、受け取ったpropsをさらに子要素に渡したいというときもありますよね。ネストした中でコンポーネントを作成して使う場合など。

ここで画像のような例を見ていきましょう。

f:id:bonoponz:20200623223820p:plain

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名を中かっこで指定すると表示したり使用することができます。

(本題)親子の要素をまたぐコンポーネント

ここで本題です。

f:id:bonoponz:20200623220159p:plain

画像のように、親要素から受け取った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>
    )
} 

流れを図解化

f:id:bonoponz:20200623213110p:plain

実際のコード

実際のコードには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}が使える時は存分に使っていきましょう。存在をお忘れなく!

参考URL

コンポジション vs 継承 – React