Хук оптимизации производительности useTransition в React
Хук оптимизации производительности
useTransition
позволяет нам
обновлять стейты без блокировки
графического интерфейса.
С помощью данного хука мы можем задать обновлению какого-нибудь стейта низкий приоритет, что позволит обновлению других стейтов иметь высокий приоритет и выполняться без задержек.
В качестве примера можно привести фильтрацию выпадающего списка товаров при введении пользователем символов в поле поиска. Конечно, сам список может отображаться с какой-то задержкой, но нам бы не хотелось, чтобы символы вводились в поле поиска с задержкой.
Давайте посмотрим, как в таких случаях
нам может помочь хук useTransition
.
Предположим, у нас есть кусок кода основного
комопонента. Давайте его проанализируем:
import { useTransition } from 'react';
import { useState } from 'react';
function App() {
const [isPending, startTransition] = useTransition();
const [filterTerm, setFilterTerm] = useState('');
const filteredProducts = filterProducts(filterTerm);
function updateFilterHandler(event) {
startTransition(() => {
setFilterTerm(event.target.value);
});
}
return (
<div>
<input type="text" onChange={updateFilterHandler} />
<ProductList products={filteredProducts} />
</div>
);
}
Здесь мы видим две переменные для
useTransition
. Переменная isPending
содержит булево значение и показывает
закончен ли процесс обновления, а
startTransition
функцию, которая
и позволяет снизить приоритет обновления:
const [isPending, startTransition] = useTransition();
Также у нас есть стейт filterTerm
,
в котором хранится вводимое в
поле ввода выражение и функция
setFilterTerm
для его установки:
const [filterTerm, setFilterTerm] = useState('');
При вводе символов в инпут у нас каждый
раз вызывается функция updateFilterHandler
,
в которой происходит обновление
filterTerm
. Именно здесь мы применяем
наш хук useTransition
, оборачивая функцию
установки setFilterTerm
в startTransition
следующим образом:
function updateFilterHandler(event) {
startTransition(() => {
setFilterTerm(event.target.value);
});
}
Таким образом, мы установили для
обновления стейта filterTerm
низкий
приоритет и наше поле ввода останется
отзывчивым.
При помощи переменной isPending
мы
можем показать пользователю, что обновление
списка еще в процессе. Выведем эту информацию
под полем ввода, пока список обновляется:
return (
<div>
<input type="text" onChange={updateFilterHandler} />
{isPending && <p>updating ...</p>}
<ProductList products={filteredProducts} />
</div>
);