[Flow Type] Reactコンポーネントchildren属性の型の書き方

Flow typeでReactコンポーネントのchildren属性の型を記載する方法をメモする。

普通の書き方

import * as React from 'react';

type Props = {
  children?: React.Node,
};

function MyComponent(props: Props) {
  return <div>{props.children}</div>;
}

ある種類の子コンポーネントのみを許可する

下記はReact.ChildrenArray<React.Element<typeof TabBarIOSItem>>でTabBarIOSItem型のみを設定できる。それ以外のものが内包されたら、flow checkエラーとなる。

import * as React from 'react';

class TabBarIOSItem extends React.Component<{}> {
  // implementation...
}

type Props = {
  children: React.ChildrenArray<React.Element<typeof TabBarIOSItem>>,
};

class TabBarIOS extends React.Component<Props> {
  static Item = TabBarIOSItem;
  // implementation...
}

<TabBarIOS>
  <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>
  <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>
  <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>
</TabBarIOS>;

子コンポーネントを一つのみに限定する

import * as React from 'react';

type Props = {
  children: React.Element<any>,
};

function MyComponent(props: Props) {
  // implementation...
}

// Not allowed! You must have children.
<MyComponent />;

// Not ok! We have multiple element children.
<MyComponent>
  <div />
  <div />
  <div />
</MyComponent>;

// This is ok. We have a single element child.
<MyComponent>
  <div />
</MyComponent>;

React.Nodeから一部の型を除く

  • React.Nodeの定義

This represents any node that can be rendered in a React application. React.Node can be undefined, null, a boolean, a number, a string, a React element, or an array of any of those types recursively.

  • 下記は文字列や数字を許可しないようにする
import * as React from 'react';

type ReactNodeWithoutStrings = React.ChildrenArray<
  | void
  | null
  | boolean
  | React.Element<any>
>;

type Props = {
  children?: ReactNodeWithoutStrings,
  // other props...
};

class View extends React.Component<Props> {
  // implementation...
}

React.Childrenを使う

  • childrenが必ず配列として存在するわけではない為、直接にchildren.map(...などを使うと、Flow checkエラーとなる。

Note: If you want methods like map() and forEach() or to handle a React.ChildrenArray as a normal JavaScript array then React provides the React.Children API to do just this. It has functions like React.Children.toArray(props.children) that you can use to treat your React.ChildrenArray as a flat array.

  • children型定義をchildren: Array<any>見たいに配列として定義できない理由

childrenの型をArrayとして定義すると、親コンポーネントにchildren属性を設定しないと怒られる。

<Parent children=...>

Reactのchildrenの意味が内包される子タグである。その為、配列型の場合、下記がLintエラーとなる

<Parent>
  <Sub />
</Parent>

  • childrenの代わりにReact.Childrenのmapやforeachを利用する
const names = React.Children.map(
  this.props.children,
  e => e.props.hoge
);

参考記事

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.