Open4

Reactのchildrenの型定義がうまくいかない問題

kage1020kage1020

React@17.0.2で複数のchildrenpropsを渡すwrapperを作るとき、ReactNodechildrenの型定義をすると怒られる

export const ChildrenWrapper = ({ children }: { children: ReactNode[] }) => {
  return (
    <div>
      {React.Children.map(children, child => {
        return React.createElement(child.type, { // ReactNode に type は存在しねえよ!
          ...{
            ...child.props, // ReactNode にprops は存在しねえよ!
            hoge: fuga
          }
        })
      })}
    </div>
  )
}
kage1020kage1020

Reactのソースコードを覗いてみると

type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;
type ReactChild = ReactElement | ReactText;
type ReactFragment = {} | ReactNodeArray;
interface ReactPortal extends ReactElement {
    key: Key | null;
    children: ReactNode;
}
type ReactText = string | number;

interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
        type: T;
        props: P;
        key: Key | null;
    }

つまり,ReactNodeReactElementをもとに定義されている.

kage1020kage1020

これを踏まえて

- export const ChildrenWrapper = ({ children }: { children: ReactNode[] }) => {
+ export const ChildrenWrapper = ({ children }: { children: ReactElement[] }) => {
  return (
    <div>
      {React.Children.map(children, child => {
        return React.createElement(child.type, {
          ...{
            ...child.props,
            hoge: fuga
          }
        })
      })}
    </div>
  )
}

と書きなおすとエラーが消えた.
*\(^o^)/*ヤッター!!

kage1020kage1020

ReactElementの使いどころは今のところchildrenを回すだけな気がする.
基本汎用性の高いReactNodeを,エラったらReactElementにする.