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
или 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,
[props],
[...children]
)
Клонирует и возвращает новый React элемент, используя элемент в качестве отправной точки. Полученный элемент будет иметь пропсы исходного элемента, а новые пропсы будут поверхностно слиты воедино. Новые дочерние элементы заменят существующие. key
и ref
из исходного элемента будут сохранены.
React.cloneElement()
почти эквивалентен:
<element.type {...element.props} {...props}>{children}</element.type>
Однако, в этом случае, сохранятся ref
. Это означает если вы получите ребёнка с ref
на нём, вы случайно не украдёте его у родителя. Вы получите тот же ref
, прикреплённый к вашему новому элементу.
Этот 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
. Это известное ограничение, которое будет устранено в будущем.