Spec-Zone.ru › Flow

Компоненты-функции и компоненты-классы

опасно

Шаблоны типизации компонентов-функций и компонентов-классов устарели. Для нового кода используйте вместо них синтаксис компонентов.

Добавление типов 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API