


Если при каждом нажатии клавиши React заново строит большой список, дайте полю актуальное значение, а списку передайте useDeferredValue(query). В учебном примере на Mentoring.digital эти два значения видно отдельно. Разница позволяет пометить список, пока он показывает результаты предыдущего запроса.
import { memo, useDeferredValue, useState } from "react";
const names = ["Анна", "Антон", "Илья", "Ирина"];
const Results = memo(function Results({ query }) {
const found = names.filter((name) =>
name.toLowerCase().includes(query.toLowerCase())
);
return <ul>{found.map((name) => <li key={name}>{name}</li>)}</ul>;
});
export default function Search() {
const [query, setQuery] = useState("");
const deferred = useDeferredValue(query);
const isStale = query !== deferred;
return (
<>
<label htmlFor="name-search">Имя</label>
<input
id="name-search"
value={query}
onChange={(event) => setQuery(event.target.value)}
/>
<section aria-busy={isStale}>
{isStale && <p>Обновляем список</p>}
<Results query={deferred} />
</section>
</>
);
}
На срочном рендере поле получает новый текст. Список может ещё получить прежний deferred. memo помогает пропустить перерисовку списка при прежнем пропсе. Затем React пытается обновить его в фоне и может прервать этот рендер ради нового ввода. Когда результаты догонят поле, отметка об обновлении исчезнет.
Четыре имени нужны для проверки логики. Чтобы заметить разницу, подставьте свой набор с уникальными ключами и измерьте рендер с помощью профилировщика React. Сравните, обновляется ли поле без ожидания списка. Если каждому рендеру списка передаётся новый объект или массив, проверьте стабильность пропсов. Иначе memo будет реже пропускать работу.
Для сетевых запросов ограничивайте частоту и отменяйте устаревшие запросы отдельно. У useDeferredValue нет заданного интервала, а перенос рендера на более низкий приоритет сам по себе не сокращает число запросов. Для очень большого списка также проверьте, можно ли рисовать только видимую часть.
Подобрать сценарий профилирования можно на практике по React или разобрать компонент с наставником по React.