Skip to main content

函数/类组件

将 Flow 类型添加到 React 组件 中的功能非常强大。输入组件后,Flow 将静态地确保你按照设计的方式使用该组件。

¥Adding Flow types to your React components is incredibly powerful. After typing your component, Flow will statically ensure that you are using the component in the way it was designed to be used.

功能组件

¥Functional Components

在功能组件中添加 Flow 类型与 向标准函数添加类型 相同。只需为 props 创建一个对象类型,Flow 将确保传递给组件的 props 与预期相匹配。

¥Adding Flow types to a functional component is the same as adding types to a standard function. Just create an object type for the props and Flow will ensure that the props passed to the component match up with what is expected.

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

向功能组件添加默认属性

¥Adding Default Props to Functional Components

向功能组件添加默认 props 的一个很好的模式是使用 使用默认值解构。通过解构函数参数中的 props,你可以为任何未传递给组件(或以值 undefined 传递)的 props 赋值。

¥A nice pattern to add default props to functional components is to use destructuring with default values. By destructuring the props in the function parameter, you can assign a value to any props that are not passed to the component (or passed with the value undefined).

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

类别组件

¥Class Components

要 Flowify 类组件,属性的类型可以作为第一个参数传递给 React.Component 类型。这与向函数组件的 props 参数添加类型具有相同的效果。

¥To Flowify a class component, the type of the props can be passed as the first argument to the React.Component type. This will have the same effect as adding types to the props parameter of a function component.

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

现在,无论我们在 React 组件中使用 this.props,Flow 都会将其视为我们定义的 Props 类型。

¥Now wherever we use this.props in our React component Flow will treat it as the Props type we defined.

注意:如果你不需要再次使用 Props 类型,你也可以内联定义它:extends React.Component<{ foo: number, bar?: string }>

¥Note: If you don't need to use the Props type again you could also define it inline: extends React.Component<{ foo: number, bar?: string }>.

React.Component<Props, State> 是一个带有两个类型参数的 泛型:属性和状态。第二个类型参数 State 是可选的。默认情况下它是 undefined,所以你可以在上面的示例中看到我们没有包含 State。我们将在下一节中了解有关状态的更多信息......

¥React.Component<Props, State> is a generic type that takes two type arguments: props and state. The second type argument, State, is optional. By default it is undefined so you can see in the example above we did not include State. We will learn more about state in the next section...

添加状态

¥Adding State

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

¥To add a type for state to your React class component: create a new object type, in the example below we name it State, and pass it as the second type argument to 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() 更新器功能,但你也可以将部分状态对象传递给 setState()

¥In the example above we are using a React setState() updater function but you could also pass a partial state object to setState().

注意:如果你不需要再次使用 State 类型,你也可以内联定义它:extends React.Component<{}, { count: number }>

¥Note: If you don't need to use the State type again you could also define it inline: extends React.Component<{}, { count: number }>.

对类组件使用默认属性

¥Using Default Props for Class Components

React 支持 defaultProps 的概念,你可以将其视为默认函数参数。当你创建一个元素并且不包含具有默认值的 prop 时,React 会用 defaultProps 中相应的值替换该 prop。Flow 也支持这个概念。要输入默认 props,请将 static defaultProps 属性添加到你的类中。

¥React supports the notion of defaultProps which you can think of as default function arguments. When you create an element and do not include a prop which has a default then React will substitute that prop with its corresponding value from defaultProps. Flow supports this notion as well. To type default props add a static defaultProps property to your class.

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 的默认属性,Flow 将确保 foo 是可选的。

¥Note: You don't need to make foo nullable in your Props type. Flow will make sure that foo is optional if you have a default prop for foo.

如果向 defaultProps 添加类型注释,则可以将类型定义为

¥If you add a type annotation to defaultProps you can define the type as

1type DefaultProps = {2  foo: number,3};

并将其传播到 Props 类型中:

¥and spread that into the Props type:

type Props = {
...DefaultProps,
bar: string,
};

这样你就可以避免重复具有默认值的属性。

¥This way you avoid duplicating the properties that happen to have a default value.

注意:你还可以通过向组件函数添加 defaultProps 属性来将这种格式的默认 props 应用于函数组件。然而,使用上述解构模式通常更简单。

¥Note: You can also apply this format of default props to functional components by adding a defaultProps property to a the component function. However, it is generally simpler to use the destructuring pattern described above.

1function MyComponent(props: {foo: number}) {}2MyComponent.defaultProps = {foo: 42};