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
);