Компоненты-функции и компоненты-классы
Шаблоны типизации компонентов-функций и компонентов-классов устарели. Для нового кода используйте вместо них синтаксис компонентов.
Добавление типов Flow к вашим компонентам React невероятно полезно. После типизации компонента Flow будет статически проверять, что вы используете его так, как он предназначен для использования.
Компоненты-функции
Добавить типы Flow к компоненту-функции — то же самое, что добавить типы к обычной функции. Просто создайте объектный тип для свойств (props), и Flow проверит, соответствуют ли переданные компоненту свойства ожидаемым.
import React from 'react';
type Props = {
foo: number,
bar?: string,
};
function MyComponent(props: Props) {
props.doesNotExist; // Error! You did not define a `doesNotExist` prop.
return <div>{props.bar}</div>;
}
<MyComponent foo={42} /> Добавление свойств по умолчанию к компонентам-функциям
Удобный способ задать свойства по умолчанию для компонентов-функций — использовать деструктуризацию со значениями по умолчанию. Деструктурируя свойства в параметре функции, вы можете присвоить значение любым свойствам, которые не переданы компоненту (или переданы со значением undefined).
import React from 'react';
type Props = {
foo?: number, // foo is optional to pass in.
bar: string, // bar is required.
};
function MyComponent({foo = 42, bar}: Props) {
// Flow knows that foo is not null or undefined
const baz = foo + 1;
}
// And we don't need to include foo.
<MyComponent bar={"abc"} />; Примечание: В React 19
defaultPropsбольше не применяется во время выполнения для компонентов-функций, а Flow никогда не считал, что это делает свойство необязательным. Вместо этого используйте значения по умолчанию при деструктуризации:
function MyComponent({foo = 42}: {foo?: number}) { /* ... */ } Компоненты-классы
Чтобы добавить типы Flow к компоненту-классу, тип свойств можно передать первым аргументом типу React.Component. Это даст тот же эффект, что и добавление типов к параметру props компонента-функции.
import React from 'react';
type Props = {
foo: number,
bar?: string,
};
class MyComponent extends React.Component<Props> {
render(): React.Node {
this.props.doesNotExist; // Error! You did not define a `doesNotExist` prop.
return <div>{this.props.bar}</div>;
}
}
<MyComponent foo={42} />; Теперь везде, где мы используем this.props в компоненте React, Flow будет считать его типом Props, который мы определили.
Примечание: Если вам не нужно повторно использовать тип
Props, его также можно определить прямо здесь:extends React.Component<{ foo: number, bar?: string }>.
React.Component<Props, State> — это обобщённый тип, который принимает два аргумента типа: свойства и состояние. Второй аргумент типа, State, необязателен. По умолчанию это undefined, поэтому, как видно из примера выше, мы не указали State. Подробнее о состоянии мы узнаем в следующем разделе...
Добавление состояния
Чтобы добавить тип состояния в компонент-класс React, создайте новый объектный тип (в примере ниже мы назвали его State) и передайте его вторым аргументом типа в React.Component.
import React from 'react';
type Props = { /* ... */ };
type State = {
count: number,
};
class MyComponent extends React.Component<Props, State> {
state: State = {
count: 0,
};
componentDidMount() {
setInterval(() => {
this.setState(prevState => ({
count: prevState.count + 1,
}));
}, 1000);
}
render(): React.Node {
return <div>Count: {this.state.count}</div>;
}
}
<MyComponent />; В примере выше мы используем функцию обновления setState() React, но также можно передать в setState() частичный объект состояния.
Примечание: Если вам не нужно повторно использовать тип
State, его также можно определить прямо здесь:extends React.Component<{}, { count: number }>.
Использование свойств по умолчанию в компонентах-классах
React поддерживает концепцию defaultProps, которую можно считать аргументами функции по умолчанию. Когда вы создаёте элемент и не указываете свойство, для которого задано значение по умолчанию, React подставляет вместо него соответствующее значение из defaultProps. Flow также поддерживает эту концепцию. Чтобы типизировать свойства по умолчанию, добавьте свойство static defaultProps в класс.
import React from 'react';
type Props = {
foo: number, // foo is required.
bar: string, // bar is required.
};
class MyComponent extends React.Component<Props> {
static defaultProps: {foo: number} = {
foo: 42, // ...but we have a default prop for foo.
};
}
// So we don't need to include foo.
<MyComponent bar={"abc"} /> Примечание: Не нужно делать
fooдопускающим значение null в типеProps. Flow обеспечит необязательностьfoo, если дляfooзадано свойство по умолчанию.
Если добавить аннотацию типа к defaultProps, можно определить тип следующим образом:
type DefaultProps = {
foo: number,
}; а затем включить его с помощью spread-оператора в тип Props:
type DefaultProps = {
foo: number,
};
type Props = {
...DefaultProps,
bar: string,
}; Так вы избежите дублирования свойств, для которых задано значение по умолчанию.
Ссылки (refs) в компонентах-классах
Чтобы использовать ссылку (ref) в компоненте-классе, добавьте свойство в класс и присвойте ему результат React.createRef.
import * as React from 'react';
class MyComponent extends React.Component<{}> {
// The `null` here is important because you may not always have the instance.
buttonRef: {current: null | HTMLButtonElement};
constructor() {
super({});
this.buttonRef = React.createRef<HTMLButtonElement>();
}
render(): React.Node {
return <button ref={this.buttonRef}>Toggle</button>;
}
} Одно существенное различие между useRef и createRef состоит в том, что createRef не принимает значение по умолчанию. Ссылка будет инициализирована значением null. Это связано с тем, что элементы DOM не существуют до первой отрисовки MyComponent, поэтому необходимо использовать значение null.
Обратите внимание: значение ссылки обёрнуто в объект со свойством current.
См. также
- Классы — как работают типы классов в Flow (актуально для компонентов-классов)
- Объекты — свойства типизируются как объектные типы
- Требование аннотаций — когда для свойств компонентов нужны явные аннотации типов
© 2013–present Facebook Inc.
Licensed under the MIT License.
https://flow.org/en/docs/react/function-and-class-components