flushSync в React – костыль или спасение?
Вчера впервые попробовал flushSyncб который подвезли в React еще в 18 версии.
Классное решение для определенных моментов! Выглядит так, будто React выдал нам костыль, но сразу предупредил: пользоваться с осторожностью.
❓ Почему это вообще нужно? (Для тех, кто не совсем в теме)
В React изменения в useState или в useEffect выглядят синхронными, но на самом деле они асинхронны.
Простой пример:
...
const [count, setCount] = useState(0);
console.log(count); // 0
setCount(1); console.log(count); // Всё ещё 0! 😲
...
Кажется, что setCount(1) сразу меняет count, но на самом деле новое значение попадёт в консоль только при следующем ререндере.
То же самое в useEffect:
...
useEffect(() => { console.log("Эффект сработал!"); }, [count]);
setCount(1); console.log("А это после setCount");
...
Лог "А это после setCount" появится в консоли раньше, чем "Эффект сработал!", потому что useEffect выполняется уже после рендера.
Как flushSync меняет поведение?
Обычно React группирует обновления (batching) и откладывает ререндер до конца текущего цикла. flushSync ломает это поведение и заставляет React сразу выполнить ререндер.
function Example() {
const [count, setCount] = React.useState(0);
const ref = React.useRef(null);
const handleClick = () => {
flushSync(() => setCount(count + 1));
console.log("Высота элемента:",
ref.current?.offsetHeight);
};
return (<button onClick={handleClick}>
Добавить {count}
</button>);
}
Что тут происходит?
Без flushSync React подождал бы до конца текущего вызова и только потом обновил DOM.
С flushSync обновление происходит немедленно, и console.log видит уже новый DOM.
React нас предупреждает
В документации прямо сказано:
"flushSync – это низкоуровневый API. Используйте его только тогда, когда вам действительно нужно измерить DOM сразу после обновления состояния."
Когда не стоит использовать flushSync?
Если можно обойтись обычными useEffect или useLayoutEffect.
Если batching работает нормально и не мешает.
Если нет необходимости немедленного ререндера (иначе можно уронить производительность).
Итог
flushSync – мощный инструмент, но использовать его нужно осознанно. Он нужен в случаях, когда важно немедленно обновить стейт и тут же прочитать DOM (например, для анимаций).
Если понравился пост присоединяйтесь к моему каналу в Telegram по ссылке https://t.me/+qbK9ZPuAocI2MWUy.
Там я делюсь своим опытом и пишу материалы которые будут полезны как новичкам, так и матерым разработчикам.