4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

props.childrenにpropsを渡す。【React/cloneElement】

Last updated at Posted at 2021-09-14

はじめに

props.childrenに対してpropsを持たせたい!となったので実装方法を探してみました。
*こちらは学習用メモです
*ドキュメントにあります。

cloneElement()

ReactにはcloneElementというAPIがあります。
今回はこちらを使用し、propsを渡していきました。

cloneElementの役割

element から新しい React 要素を複製して返します。結果の要素は元の要素の props と新しい props が浅くマージされたものを持ちます。新しい子要素は既存の子要素を置き換えます。key と ref は元の要素から保持されます。(引用: https://ja.reactjs.org/docs/react-api.html)

上記の通りにelementから新しいReact要素を複製という部分のelementがprops.childrenに値するという考えです。
使用する際はkey と ref は元の要素から保持されます。こちらに注意しながら実装を行うといいかもしれません。

cloneElement/引数

React.cloneElement(
  element, // <= 複製するelement
  [props], // <= 複製するelementに適応させるprops
  [...children] // <=複製するelementのchildrenとなる要素を指定
)

使用例

今回紹介する例はあくまで例なので、都合上props.childrenに渡したいという時に使用することと
本当にコンポーネント設計は正しいか確認の必要があると思います。

親コンポーネントの作成

ItemList.tsx
import { Item } from './Item'
import { ItemChild } from './ItemChild'

export const ItemList = () => {
  return (
    <div>
      <Item>
        <ItemChild />
      </Item>
    </div>

  )
}

props.childrenにpropsを渡す設定

Item.tsx

export const Item = (props) => {

  const items = [
    {id: 1, name: 'hoge1'},
    {id: 2, name: 'hoge2'}
  ]
  // ここで渡す設定を行うコンポーネントを作成。
  const ChildrenItem = (props) => {
    // children === props.children, 渡したいprops === ...newProps
    const { children, ...newProps } = props;
    const childrenWithProps = React.Children.map(children, (child: React.ReactElement) => React.cloneElement(child, { ...newProps }));
  }

  return (
    { 
      items.map((item, index) => {
         // item、 indexがprops.childrenに渡したいprops
        <ChildrenItem item={item} index={index}> 
          {props.children}
        </ChildrenItem>
      }
    }
  )
}

MyItemコンポーネント (propsを渡される props.children)

MyItem.tsx
export const MyItem = (props) => {
 // ItemListコンポーネントではpropsを設定していないがcloneElementの設定により受け取ることができる。
  const { item, index } = props

  return (
    <div>
      <div>index: { index }</div>
      <div>itemName: { item.name }</div>
    </div>

  )
}

終わりに

実際に開発で使用した実装内容だと必要になったのですが、propsの順を追う時に若干厄介になる可能性があるので使用の際は本当に使う必要があるのかなど考える必要があることがわかりました。

参考

【React の最上位 API】 cloneElement()
https://qiita.com/NeGI1009/items/e6ad87320391c836bcf9
React.Chilrenについてあまり説明をしていなかったので知りたい方は下記
Reactのchildren探訪

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?