React API верхнего уровня

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

Обзор

Компоненты

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

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

React-компоненты также могут быть объявлены как функции, которые могут быть обёрнуты:

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

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

Читайте Использование React без JSX, чтобы получить подробную информацию.

Трансформация элементов

React предоставляет несколько API-методов для управления элементами:

Фрагменты

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

Рефы

Задержка (Suspense)

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

Хуки

Хуки — это новое дополнение в React 16.8. Они позволяют вам использовать состояние и другие функции React без написания класса. У хуков есть свой раздел документации и отдельный API-справочник:


Справочник

React.Component

React.Component — это базовый класс для компонентов React, объявленных как ES6-классы:

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

Со списком методов и свойств базового класса React.Component можно ознакомиться в API-справочнике по 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) {
  /* рендер с использованием пропсов */
});

React.memo — это компонент высшего порядка.

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

React.memo затрагивает только изменения пропсов. Если функциональный компонент обёрнут в React.memo и использует useState, useReducer или useContext, он будет повторно рендериться при изменении состояния или контекста.

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

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

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

Примечание

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


createElement()

React.createElement(
  type,
  [props],
  [...children]
)

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

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


cloneElement()

React.cloneElement(
  element,
  [config],
  [...children]
)

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

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

<element.type {...element.props} {...props}>{children}</element.type>

Тем не менее, в этом случае также сохранятся ref. Это означает если вы получите ребёнка с ref на нём, вы случайно не украдёте его у родителя. Вы получите тот же ref, прикреплённый к вашему новому элементу. Новые ref или key заменяет существующие (если они есть).

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


createFactory()

React.createFactory(type)

Возвращает функцию, которая создаёт элементы React заданного типа. Как и React.createElement(), аргументом type может быть строка содержащая имя тега (например, '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 передавая их по очереди в 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 будет вызывать эту функцию с пропсами и рефом в качестве двух аргументов. Эта функция должна возвращать узел React.

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

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

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

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

Читайте Перенаправление рефов, чтобы получить подробную информацию.

React.lazy

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

Вы можете узнать, как этим пользоваться из нашей документации по разделению кода. Вы также можете посмотреть эту статью с объяснением, как использовать этот метод более подробно.

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

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

Примечание

Использование React.lazy с динамическим импортом требует доступности Promises в среде JS. Для IE11 и ниже необходим полифил.

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

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

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

Примечание:

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