メインコンテンツにスキップ

関数/クラスコンポーネント

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