
Комментарии 8
Спасибо за статью, а можно еще сделать разбор новых хуков, которые стали доступны с React 19 помимо useOptimistic?
Спасибо за отзыв!
Да, планирую сделать разбор и остальных новых хуков из React 19, чтобы охватить все интересные возможности (будет отдельная статья). А пока можете заглянуть в мою подробную статью о хуке useActionState: https://habr.com/ru/articles/870216/ - там тоже есть немало интересных идей по оптимизации и управлению состоянием. Спасибо, что читаете!
Подскажите пожалуйста, могу ошибаться, разве в вашем примере с useDeferredValue хуком при изменении состояния не произойдет ререндер как компонента, который содержит стейт поиска, так и дочерний компонент, куда передаётся deffered значение пропом?
Спасибо за коментарий, отличное наблюдение.useDeferredValue помогает распределять приоритеты рендеринга, чтобы сохранить отзывчивость интерфейса (например, при вводе текста). Однако, как подчёркивает и документация, для полного раскрытия потенциала этого хука тяжёлый компонент желательно обернуть в React.memo. Без мемоизации он будет перерендериваться при каждом обновлении родителя, и все преимущество теряется. Поправлю пример в стате, чтобы сразу показать наглядное использование вместе с memo.
Спасибо, что обратили на это внимание!
Полезная информация для меня, дизайнера
Спасибо, только у вас использование функции addOptimisticOrder до ее объявления - плохая практика.
Простите, но кажется пример useTransition некорректный.
Если вы добавите в фильтрацию реальную задержку, то увидите что никакой отзывчивости нет, интерфейс виснет при вводе каждого символа:
const syncSleep = (time: number) => {
const startTime = new Date();
while (new Date().getTime() - startTime.getTime() < time) {}
};
// Некритичное обновление вынесем в startTransition
startTransition(() => {
syncSleep(3000); // <------- Ставим реальную задержку
const filtered = allItems.filter((item) =>
item.text.toLowerCase().includes(value.toLowerCase())
);
setFilteredItems(filtered);
});Причем виснет он даже не на 3 секунды, а на 3 * число введенных символов. Т.е. абсолютно никакого выигрыша.
Можете сами проверить:
https://codesandbox.io/p/devbox/objective-http-ph3lsl?workspaceId=ws_Vn7GNkZok9ujTbLbsTAhER
Время редактирования комментария закончилось, так что приходится писать новый.
Попробовал переписать вот так, опираясь на примеры из документации:
// Некритичное обновление вынесем в startTransition
startTransition(() => {
setTimeout(() => {
syncSleep(3000);
const filtered = allItems.filter((item) =>
item.text.toLowerCase().includes(value.toLowerCase())
);
startTransition(() => {
setFilteredItems(filtered);
});
}, 0);
});Интерфейс все равно подвисает, что понятно, но по крайней мере при быстром вводе символы появляются раньше, чем все дофильтруется.
Оптимизация React-приложений: Используем useTransition, useDeferredValue и useOptimistic для плавного UI