Переходы с отложенным обновлением в React — это механизм (появился в React 18), позволяющий помечать некоторые обновления состояния как "не срочные". Это нужно, чтобы React мог приостановить их выполнение и сначала обработать более важные (срочные) обновления — так интерфейс остаётся отзывчивым даже при тяжёлых вычислениях.
Реализовать данный механизм позволяет хук useTransition.
Когда использовать переходы с отложенным обновлением?
Переходы с отложенным обновлением используются, когда у вас есть:
- Медленная операция, которая может заморозить интерфейс
- Обновления, которые не критичны немедленно
- Результаты поиска, занимающие некоторое время для отображения
Как это работает
- Вы оборачиваете изменение состояния в
startTransition(из хукаuseTransition). - React отмечает это обновление как "переход" — то есть некритичное по времени.
- Если в этот момент возникает срочное действие (например, ввод в поле), React приостанавливает "переход" и сначала обрабатывает срочное обновление.
- Когда интерфейс свободен, React возвращается к отложенному обновлению и завершает его.
Простой пример
Вот простой пример, демонстрирующий, как использовать переходы с отложенным обновлением в поиске:
Пример
import { useState, useTransition } from 'react';
function SearchBar() {
const [text, setText] = useState('');
const [results, setResults] = useState('');
const [isPending, startTransition] = useTransition();
const handleChange = (e) => {
// Срочно: мгновенно обновить ввод
setText(e.target.value);
// Не срочно: обновление результатов поиска
startTransition(() => {
setResults(e.target.value);
});
};
return (
<div>
<input value={text} onChange={handleChange} />
{isPending ? (
<p>Загрузка...</p>
) : (
<p>Результаты поиска для: {results}</p>
)}
</div>
);
}
В этом примере:
- Поле ввода обновляется сразу (срочное обновление)
- Обновление результатов поиска отмечено как отложенный переход (несрочное)
- Сообщение загрузки отображается пока выполняется отложенный переход
Пример из реального мира
Более практичный пример с медленно работающим поиском:
Пример
import { useState, useTransition } from 'react';
function SearchResults({ query }) {
// Имитация медленных результатов поиска
const items = [];
if (query) {
for (let i = 0; i < 1000; i++) {
items.push(<li key={i}>Результат для {query} - {i}</li>);
}
}
return <ul>{items}</ul>;
}
function App() {
const [input, setInput] = useState('');
const [query, setQuery] = useState('');
const [isPending, startTransition] = useTransition();
const handleChange = (e) => {
// Срочно: обновление поля ввода
setInput(e.target.value);
// Не срочно: обновление результатов поиска
startTransition(() => {
setQuery(e.target.value);
});
};
return (
<div>
<input
type="text"
value={input}
onChange={handleChange}
placeholder="Наберите для поиска..."
/>
{isPending && <p>Загрузка результатов...</p>}
<SearchResults query={query} />
</div>
);
}
Как работает этот пример:
- Когда вы вводите текст в поле, оно обновляется моментально
- Обновление результатов поиска помещено в
startTransition - Пока идет обновление результатов,
isPendingравен true - Интерфейс остается отзывчивым даже при большом количестве результатов
Хук useTransition
Хук useTransition возвращает два элемента:
isPending: показывает, активен ли сейчас отложенный переходstartTransition: функция для маркировки обновлений как отложенный переход
Примечание: Используйте переходы с отложенным обновлением только для несрочных обновлений. Например, ввод текста в поле должен быть срочным, а фильтрация большого списка может стать отложенным переходом.