4.1 React


React - это точка входа в библиотеку React. Если вы загружаете React из тега <script>, эти API верхнего уровня доступны в глобальном объекте React. Если вы используете ES6 с npm, вы можете написать import React from 'react'. Если вы используете ES5 с npm, вы можете написать var React = require('react')



4.1.1.1 Обзор


4.1.1.1.1 Компоненты

React-компоненты позволяют разделить UI на самостоятельные, многоразовые фрагменты и работать с каждой частью отдельно. React-компоненты могут быть определены с помощью подкласса React.Component или React.PureComponent.

Если вы не используете классы ES6, вы можете вместо этого использовать модуль create-react-class. Дополнительную информацию см. в разделе Использование React без ES6 .

Компоненты React также могут быть определены как функции, которые могут быть упакованы в:


4.1.1.1.2 Создание React-элементов

Рекомендуется использовать JSX для описания того, как должен выглядеть ваш пользовательский интерфейс. Каждый элемент JSX является просто синтаксическим сахаром для вызова React.createElement(). Как правило, вы не будете использовать следующие методы, если используете JSX.

Дополнительную информацию см. в разделе React без JSX .


4.1.1.1.3 Преобразование элементов

React также различные API для манипуляции элементами:


4.1.1.1.4 Фрагменты

React также предоставляет компонент для отрисовки множества элементов без обёртки:


4.1.1.1.5 Ссылки


4.1.1.1.6 Приостановка (Suspense)

Приостановка позволяет компонентам «подождать» что-либо перед отрисовкой. Сегодня приостановка поддерживает только один вариант использования: динамическая загрузка компонентов с помощью React.lazy. В будущем она будет поддерживать и другие варианты использования, такие как выборка данных.


4.1.1.2 Справка


React.Component

React.Component является базовым классом для компонентов React, когда они определены с использованием классов ES6.


Код
    
  class Hello extends React.Component {
    render() {
      return <h1>Привет, {this.props.name}</h1>;
    }
  }
  

См. справочник API React.Component для поиска методов и свойств, связанных с базовым классом React.Component.


React.PureComponent

React.PureComponent такой же, как и React.Component. Разница между ними заключается в том, что React.Component не реализует shouldComponentUpdate(), а React.PureComponent реализует его с помощью неглубокого сравнения свойств и состояния.

Если метод render() компонента React отображает тот же результат с теми же свойствами и состоянием, вы в некоторых случаях можете использовать React.PureComponent для повышения производительности.


Замечание.

Метод shouldComponentUpdate() компонента React.PureComponent только поверхностно сравнивает объекты. Если они содержат сложные структуры данных, это может привести к ложным отрицаниям для более глубоких сравнений. Расширяйте PureComponent только в том случае, если вы будете иметь простые свойства и состояние, или используйте forceUpdate(), когда вы знаете, что изменились структуры данных. Или рассмотрите возможность использования неизменяемых объектов для быстрого сравнения вложенных данных.

Кроме того, метод shouldComponentUpdate() компонента React.PureComponent пропускает обновления свойств для всего поддерева компонента. Убедитесь, что все дочерние компоненты также «чисты».



React.memo


Код
    
  const MyComponent = React.memo(function MyComponent(props) {
    /* Отрисовка с использованием props */
  });
  

React.memo является компонентом более высокого порядка. Он похож на React.PureComponent, но предназначен для компонентов-функций.

Если ваш компонент-функция отображает один и тот же результат при неизменных props, вы можете заключить его в вызов React.memo для повышения производительности в некоторых случаях, мемоизируя результат. Это означает, что React пропустит отрисовку компонента, повторно используя последний результат отрисовки.

По умолчанию он только поверхностно сравнивает сложные объекты в объекте props. Если вы всё же хотите контролировать сравнение, вы также можете предоставить пользовательскую функцию сравнения в качестве второго аргумента.


Код
    
  function MyComponent(props) {
    /* Отрисовка с использованием props */
  }
  function areEqual(prevProps, nextProps) {
    /*
      возвращает true, если передача nextProps для отрисовки
      вернет тот же результат, что и передача prevProps. В
      противном случае вернет false
    */
  }
  export default React.memo(MyComponent, areEqual);
  

Этот метод существует только для оптимизации производительности. Не полагайтесь на него, чтобы «предотвратить» отрисовку, так как это может привести к ошибкам.


Внимание!

В отличие от метода shouldComponentUpdate() для компонентов классов, функция areEqual возвращает значение true, если props равны, и значение false, если значения не равны. Это инверсия shouldComponentUpdate.


createElement()


Код
    
  React.createElement(
    type,
    [props],
    [...children]
  )
  

Создаёт и возвращает новый элемент React указанного типа. Типизированный аргумент может быть либо строкой имени тега (например, 'div' или 'span'), либо типом компонента React (класс или функция), либо фрагментом React.

Код, написанный с помощью JSX, будет конвертирован в вызовы React.createElement(). Обычно вы не вызываете React.createElement(), если используете JSX. См. React без JSX , чтобы узнать больше.


cloneElement()


Код
    
  React.cloneElement(
    element,
    [props],
    [...children]
  )
  

Клонировать и вернуть новый элемент React, используя element в качестве отправной точки. Получившийся элемент будет иметь свойства оригинального элемента с новыми свойствами, смердженными неглубоко. Новые потомки заменят существующих потомков. key и ref из исходного элемента будут сохранены.

React.cloneElement() почти эквивалентен:


Код
    
  <element.type {...element.props} {...props}>{children}</element.type>
  

Однако он также сохраняет и ссылки. Это означает, что если вы получите потомка с ref на нем, вы не сможете случайно украсть этот атрибут у своего предка. Вы получите тот же ref, присоединенный к вашему новому элементу.

Этот API был введен как замена устаревшего React.addons.cloneWithProps().


createFactory()


Код
    
  React.createFactory(type)
  

Возвращает функцию, которая создает элементы React данного типа. Подобно React.createElement(), аргумент типа может быть либо строкой имени тега (например, 'div' или 'span'), либо типом компонента React (класс или функция), либо фрагментом React.

Этот помощник считается устаревшим. Вместо него рекомендуется использовать либо JSX, либо React.createElement().

Как правило, вы не вызываете напрямую React.createFactory(), если используете JSX. См. React без JSX , чтобы узнать больше.


isValidElement()


Код
    
  React.isValidElement(object)
  

Проверяет, является ли объект элементом React. Возвращает true или false.


React.Children

React.Children предоставляет утилиты для работы с непрозрачной структурой данных this.props.children.


React.Children.map


Код
    
  React.Children.map(children, function[(thisArg)])
  

Вызывает функцию для каждого дочернего элемента, содержащегося в children, с this установленным в thisArg. Если children представляет собой массив, он будет пройден и функция будет вызвана для каждого его элемента. Если children имеет значение null или undefined, метод вернет значение null или undefined, а не массив.


Внимание!

Если children - это Fragment, он будет рассматриваться как единичный потомок и не будет пройден.


React.Children.forEach


Код
    
  React.Children.forEach(children, function[(thisArg)])
  

То же, что и React.Children.map(), но не возвращает массив.


React.Children.count


Код
    
  React.Children.count(children)
  

Возвращает общее количество компонентов в children, равное количеству раз, которое будет вызван коллбэк, переданный для map или forEach.


React.Children.only


Код
    
  React.Children.only(children)
  

Проверяет, что children имеет только одного потомка (React-элемент) и возвращает его. Иначе выбрасывает исключение.



Замечание.

React.Children.only() не принимает значение, возвращаемое React.Children.map(), потому что оно является массивом, а не элементом React.


React.Children.toArray


Код
    
  React.Children.toArray(children)
  

Возвращает непрозрачную структуру данных children как плоский массив с ключами, назначенными каждому потомку. Это полезно, если вы хотите манипулировать коллекциями потомков в ваших методах отрисовки, особенно если вы хотите изменить порядок или обрезать this.props.children, прежде чем передавать его.


Внимание!

React.Children.toArray() изменяет ключи, чтобы сохранить семантику вложенных массивов при выравнивании списков потомков. То есть toArray будет являться префиксом каждого ключа в возвращаемом массиве, так что ключ каждого элемента получает пространство имен содержащего его входного массива.


React.Fragment

Компонент React.Fragment позволяет возвращать множество элементов из метода render() без создания дополнительного элемента DOM:


Код
    
  render() {
    return (
      <React.Fragment>
        Какой-то текст.
        <h2>Заголовок</h2>
      </React.Fragment>
    );
  }
  

Вы также можете использовать сокращенный синтаксис <></>. Для получения дополнительной информации см. React v16.2.0: Улучшенная поддержка фрагментов.


React.createRef

React.createRef создает ссылку, которая может быть присоединена к элементу React с помощью атрибута ref:


Код
    
  class MyComponent extends React.Component {
    constructor(props) {
      super(props);
  
      this.inputRef = React.createRef();
    }
  
    render() {
      return <input type="text" ref={this.inputRef} />;
    }
  
    componentDidMount() {
      this.inputRef.current.focus();
    }
  }
  


React.forwardRef

React.forwardRef создает компонент React, передающий атрибут ref, который он сам же получает, другому компоненту, расположенному ниже в дереве. Несмотря на то, что этот подход не очень распространен, он особенно полезен в двух сценариях:

React.forwardRef принимает функцию отрисовки в качестве аргумента. React вызовет эту функцию с двумя аргументами props и ref. Эта функция должна возвращать узел React.


Код
    
  const FancyButton = React.forwardRef((props, ref) => (
    <button ref={ref} className="FancyButton">
      {props.children}
    </button>
  ));

  // Сейчас вы можете получить ref, присоединенную к DOM button:
  const ref = React.createRef();
  <FancyButton ref={ref}>Click me!</FancyButton>;
  

В приведенном выше примере React передает ссылку ref, переданную элементу <FancyButton ref = {ref}>, функции отрисовки внутри вызова React.forwardRef в качестве второго аргумента. Затем эта функция передает ref в элемент <button ref = {ref}>.

В результате после того, как React присоединит ref, ref.current будет указывать непосредственно на элемент <button> DOM.

Для получения дополнительной информации см. раздел Передача ссылок.


React.lazy

React.lazy() позволяет вам определять компонент, который загружается динамически. Это помогает уменьшить размер бандла, отложив загрузку компонентов, которые не используются во время начальной отрисовки.

Более подробно о его использовании вы можете узнать из раздела документации по разделению кода. Также можете изучить эту статью.


Код
    
  // Этот компонент подгружается динамически
  const SomeComponent = React.lazy(() => import('./SomeComponent'));
  

Обратите внимание, что для отрисовки ленивых компонентов требуется, чтобы в отрисовываемом дереве находился компонент <React.Suspense>. К тому же с его помощью вы можете указать индикатор загрузки.


React.Suspense

React.Suspense позволяет указать индикатор загрузки в случае, если некоторые компоненты в дереве под ним еще не готовы к отрисовке (подгружаются). Сегодня отложенная загрузка компонентов - это единственный вариант использования, поддерживаемый <React.Suspense>:


Код
    
  // Этот компонент подгружается динамически
  const OtherComponent = React.lazy(() => import('./OtherComponent'));
  
  function MyComponent() {
    return (
      // Отобраает <Spinner> пока подгружается OtherComponent
      <React.Suspense fallback={<Spinner />}>
        <div>
          <OtherComponent />
        </div>
        </React.Suspense>
        );
  }
  

Это задокументировано в разделе по разбиению кода. Обратите внимание, что ленивые компоненты могут быть глубоко внутри дерева Suspense - ему не обязательно оборачивать каждый из них. Лучше всего размещать <Suspense> там, где вы хотите видеть индикатор загрузки, а lazy() использовать везде, где вы хотите выполнить разбиение кода.

Хотя это не поддерживается сегодня, в будущем мы планируем позволить Suspense обрабатывать больше сценариев, например таких как извлечение данных. Вы можете прочитать об этом в нашем плане действий.


Внимание!

React.lazy() и <React.Suspense> пока не поддерживаются ReactDOMServer. Это известное ограничение, которое в будущем будет устранено.