В марте 2022 года команда React объявила об официальном выпуске React 18. В этом выпуске появилось множество новых функций, направленных на повышение производительности, основанных на концепции «одновременного рендеринга». Идея параллельного рендеринга состоит в том, чтобы сделать процесс рендеринга в DOM прерываемым.

Среди новых функций — пять хуков: useId, useTransition, useDerredValue, useSyncExternalStore и useInsertionEffect.

Реагировать на использование Transition Hook

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

Компонент SearchPage

Эта простая программа имитирует поисковую систему, которая обновляет два состояния — поле ввода и некоторые результаты поиска.

импорт { состояние использования } из "реагировать";
функцияСтраница поиска() {
const [ввод, setInput] = useState ("")
константа [список, setList] = useState([]);

константа размер списка = 30000

функцияручка изменения(е) {
setInput(е.цель.ценность);
константа элементы списка = [];

за (позволять я = 0; я списокЭлементы.толкать(е.цель.ценность);
}

установитьСписок (элементы списка);
}

возвращаться (
<див>
<этикетка>Искать в Интернете: </label>
<тип ввода="текст" значение = {input} onChange = {handleChange} />

{список.map((элемент, индекс) => {
возвращаться <ключ div={индекс}>{вещь}</div>
})}
</div>
);
}
экспортдефолт страница поиска;

Обновленный компонент приложения

импорт Страница поиска из "./Компоненты/Страница поиска";

функцияПриложение() {
возвращаться (
<див>
< Страница поиска/>
</div>
);
}

экспортдефолт Приложение;

Приведенный выше код отображает приложение React с полем ввода:

Когда вы начнете вводить символы в поле, внизу появится 30 000 копий набранного текста:

Если вы набираете несколько символов в быстрой последовательности, вы должны заметить задержку. Он влияет на время, необходимое для появления символов как в поле ввода, так и в «области результатов поиска». Это связано с тем, что React запускает оба обновления состояния одновременно.

Если демонстрация работает слишком медленно или слишком быстро для вас, попробуйте настроить размер списка значение соответственно.

Вставка хука useTransition в приложение позволит вам установить приоритет одного обновления состояния над другим.

Использование хука useTransition

импорт {useState, useTransition} из "реагировать";

функцияСтраница поиска() {
константа [ожидание, startTransition] = useTransition();
const [ввод, setInput] = useState ("")
константа [список, setList] = useState([]);

константа размер списка = 30000

функцияручка изменения(е) {
setInput(е.цель.ценность);
начальный переход (() => {
константа элементы списка = [];

за (позволять я = 0; я списокЭлементы.толкать(е.цель.ценность);
}

установитьСписок (элементы списка);
});
}

возвращаться (
<див>
<этикетка>Искать в Интернете: </label>
<тип ввода="текст" значение = {input} onChange = {handleChange} />

{находится на рассмотрении? "...Загрузка результатов": list.map((элемент, индекс) => {
возвращаться <ключ div={индекс}>{вещь}</div>
})}
</div>
);
}

экспортдефолт страница поиска;

Обновление вашего Страница поиска компонент с приведенным выше кодом будет отдавать приоритет полю ввода над «областью результатов поиска». Это простое изменение имеет очевидный эффект: вы должны немедленно начать видеть текст, который вы вводите в поле ввода. Только «область результатов поиска» по-прежнему будет иметь небольшую задержку. Это связано с startTransitionинтерфейс прикладного программирования (API) из хука useTransition.

Код, отображающий результаты поиска в пользовательском интерфейсе, теперь использует startTransition API. Это позволяет полю ввода прерывать обновление состояния результатов поиска. Когда находится на рассмотрении() Функция отображает «…Результат загрузки», это указывает на то, что происходит переход (из одного состояния в другое).

Реагировать на хук useDeferredValue

Хук useDeferredValue позволяет отложить повторный рендеринг необоснованного обновления состояния. Как и хук useTransition, хук useDeferredValue является хуком параллелизма. Хук useDeferredValue позволяет состоянию сохранять исходное значение, пока оно находится в процессе перехода.

Компонент SearchPage с хуком useDeferredValue()

импорт { useState, useTransition, useDeferredValue } из "реагировать";

функцияСтраница поиска() {

константа [,startTransition] = useTransition();
const [ввод, setInput] = useState ("")
константа [список, setList] = useState([]);

константа размер списка = 30000

функцияручка изменения(е) {
setInput(е.цель.ценность);
начальный переход (() => {
константа элементы списка = [];

за (позволять я = 0; я списокЭлементы.толкать(е.цель.ценность);
}

установитьСписок (элементы списка);
});
}
константа deferredValue = useDeferredValue (ввод);
возвращаться (
<див>
<этикетка>Искать в Интернете: </label>
<тип ввода="текст" значение = {input} onChange = {handleChange} />

{список.map((элемент, индекс) => {
возвращаться <ключ div = {индекс} ввод = {deferredValue} >{вещь}</div>
})}
</div>
);
}

экспортдефолт страница поиска;

В приведенном выше коде вы увидите, что находится на рассмотрении() функции больше нет. Это потому, что отложенное значение переменная из хука useDeferredValue заменяет находится на рассмотрении() функция во время перехода состояния. Вместо того, чтобы список результатов поиска обновлялся при вводе нового символа, он будет сохранять свои старые значения, пока приложение не обновит состояние.

Реагировать на хук useSyncExternalStore

В отличие от хуков useTransition и useDeferredValue, которые работают с кодом приложения, useSyncExternalStore работает с библиотеками. Это позволяет вашему приложению React подписываться и читать данные из внешних библиотек. Хук useSyncExternalStore использует следующее объявление:

константа состояние = useSyncExternalStore (подписаться, getSnapshot [, getServerSnapshot]);

Эта подпись содержит следующее:

  • государство: значение хранилища данных, которое возвращает хук useSyncExternalStore.
  • подписываться: регистрирует обратный вызов при изменении хранилища данных.
  • получитьснимок: возвращает текущее значение хранилища данных.
  • getServerSnapshot: возвращает снимок, используемый во время рендеринга сервера.

С помощью useSyncExternalStore вы можете подписаться на все хранилище данных или определенное поле в хранилище данных.

Реагировать на использование хука InsertionEffect

Хук useInsertionEffect — еще один новый хук React, который работает с библиотеками. Однако вместо хранилищ данных хук useInsertionEffect работает с библиотеками CSS-in-JS. Этот хук решает проблемы с производительностью рендеринга стилей. Он стилизует DOM перед чтением макета в хуке useLayoutEffect.

Реагировать на хук useId

Вы используете хук useId в ситуациях, когда требуются уникальные идентификаторы (кроме ключей в списке). Его основная цель — генерировать идентификаторы, которые остаются уникальными для клиента и сервера, избегая ошибки несоответствия гидратации сервера React. Хук useId использует следующее объявление:

константа идентификатор = использовать идентификатор ()

В декларации я бы уникальная строка, включающая : токен. После объявления вы можете пройти я бы переменная непосредственно к элементу (элементам), который в ней нуждается.

Какую ценность эти новые хуки добавляют в React?

Хуки useTransition и useDeferredValue — это хуки кода приложения. Благодаря параллельному рендерингу они повышают производительность приложений. Хук useId устраняет ошибку несоответствия гидратации, создавая уникальные идентификаторы для клиента и сервера.

Перехватчики useSyncExternalStore и useInsertionEffect работают с внешними библиотеками для облегчения параллельного рендеринга. Хук useInsertionEffect работает с библиотеками CSS-in-JS. Хук useSyncExternalStore работает с библиотеками хранилища данных, такими как хранилище Redux.

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