跳至主要内容

函数/类组件

在你的 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,你可以为任何未传递给组件的 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> 是一个 泛型类型,它接受两个类型参数:props 和 state。第二个类型参数 State 是可选的。默认情况下它为 undefined,因此你可以在上面的示例中看到我们没有包含 State。我们将在下一节中详细了解 state...

添加 state

要为你的 React 类组件添加 state 类型:创建一个新的对象类型,在下面的示例中我们将其命名为 State,并将其作为第二个类型参数传递给 React.Component

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 将用其在 defaultProps 中的对应值替换该 prop。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 设置为可空。如果你为 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};