関数/クラスコンポーネント
ReactコンポーネントにFlow型を追加することは非常に強力です。コンポーネントに型を付けると、Flowはコンポーネントが設計どおりに使用されていることを静的に保証します。
関数コンポーネント
関数コンポーネントにFlow型を追加することは、標準関数に型を追加することと同じです。 propsのオブジェクト型を作成するだけで、Flowはコンポーネントに渡されたpropsが期待されるものと一致することを保証します。
1import React from 'react';2
3type Props = {4 foo: number,5 bar?: string,6};7
8function MyComponent(props: Props) {9 props.doesNotExist; // Error! You did not define a `doesNotExist` prop. 10
11 return <div>{props.bar}</div>;12}13
14<MyComponent foo={42} />
9:9-9:20: Cannot get `props.doesNotExist` because property `doesNotExist` is missing in `Props` [1]. [prop-missing]
関数コンポーネントにデフォルトPropsを追加する
関数コンポーネントにデフォルトのpropsを追加するための優れたパターンは、デフォルト値を持つ分割代入を使用することです。 関数パラメータでpropsを分割代入することにより、コンポーネントに渡されない(または値undefined
で渡される)propsに値を割り当てることができます。
1import React from 'react';2
3type Props = {4 foo?: number, // foo is optional to pass in.5 bar: string, // bar is required.6};7
8function MyComponent({foo = 42, bar}: Props) {9 // Flow knows that foo is not null or undefined10 const baz = foo + 1;11}12
13// And we don't need to include foo.14<MyComponent bar={"abc"} />;
クラスコンポーネント
クラスコンポーネントをFlowに対応させるには、propsの型をReact.Component
型の最初の引数として渡すことができます。 これは、関数コンポーネントのprops
パラメータに型を追加するのと同じ効果があります。
1import React from 'react';2
3type Props = {4 foo: number,5 bar?: string,6};7
8class MyComponent extends React.Component<Props> {9 render(): React.Node {10 this.props.doesNotExist; // Error! You did not define a `doesNotExist` prop. 11
12 return <div>{this.props.bar}</div>;13 }14}15
16<MyComponent foo={42} />;
10:16-10:27: Cannot get `this.props.doesNotExist` because property `doesNotExist` is missing in `Props` [1]. [prop-missing]
これで、Reactコンポーネントでthis.props
を使用するたびに、Flowはそれを定義したProps
型として扱います。
**注:**
Props
型を再度使用する必要がない場合は、インラインで定義することもできます:extends React.Component<{ foo: number, bar?: string }>
。
React.Component<Props, State>
は、2つの型引数(propsとstate)をとるジェネリック型です。 2番目の型引数であるState
はオプションです。 デフォルトではundefined
なので、上記の例ではState
を含めていません。 次のセクションでstateについて詳しく学びます...
Stateの追加
Reactクラスコンポーネントにstateの型を追加するには:新しいオブジェクト型を作成します(以下の例ではState
という名前を付けています)、そしてそれをReact.Component
の2番目の型引数として渡します。
1import React from 'react';2
3type Props = { /* ... */ };4
5type State = {6 count: number,7};8
9class MyComponent extends React.Component<Props, State> {10 state: State = {11 count: 0,12 };13
14 componentDidMount() {15 setInterval(() => {16 this.setState(prevState => ({17 count: prevState.count + 1,18 }));19 }, 1000);20 }21
22 render(): React.Node {23 return <div>Count: {this.state.count}</div>;24 }25}26
27<MyComponent />;
上記の例では、React setState()
アップデータ関数を使用していますが、部分的なstateオブジェクトをsetState()
に渡すこともできます。
**注:**
State
型を再度使用する必要がない場合は、インラインで定義することもできます:extends React.Component<{}, { count: number }>
。
クラスコンポーネントにデフォルトPropsを使用する
Reactは、デフォルトの関数引数と考えることができるdefaultProps
の概念をサポートしています。 要素を作成し、デフォルトを持つpropを含めない場合、ReactはそのpropをdefaultProps
の対応する値に置き換えます。 Flowもこの概念をサポートしています。 デフォルトのpropsに型を付けるには、クラスにstatic defaultProps
プロパティを追加します。
1import React from 'react';2
3type Props = {4 foo: number, // foo is required.5 bar: string, // bar is required.6};7
8class MyComponent extends React.Component<Props> {9 static defaultProps: {foo: number} = {10 foo: 42, // ...but we have a default prop for foo.11 };12}13
14// So we don't need to include foo.15<MyComponent bar={"abc"} />
**注:**
Props
型でfoo
をnullableにする必要はありません。foo
のデフォルトpropがある場合、Flowはfoo
がオプションであることを確認します。
defaultProps
に型注釈を追加する場合、型を次のように定義できます
1type DefaultProps = {2 foo: number,3};
そしてそれをProps
型にスプレッドします
type Props = {
...DefaultProps,
bar: string,
};
こうすることで、デフォルト値を持つプロパティの重複を避けることができます。
**注:** コンポーネント関数に
defaultProps
プロパティを追加することで、この形式のデフォルトpropsを関数コンポーネントにも適用できます。 ただし、一般的には、上記で説明した分割代入パターンを使用する方が簡単です。1function MyComponent(props: {foo: number}) {}2MyComponent.defaultProps = {foo: 42};