Этот вопрос исследует методы оптимизации ре-рендеров при множественных обновлениях состояния в React.
В React 17 можно использовать ReactDOM.unstable_batchedUpdates() для группировки нескольких обновлений состояния в один ре-рендер. Также в некоторых случаях автоматическое батчинг работает в обработчиках событий React. В React 18 батчинг работает автоматически во всех сценариях, включая асинхронные операции.
Батчинг обновлений состояния позволяет уменьшить количество ре-рендеров и повысить производительность.
Методы батчинга в React 17:
1. unstable_batchedUpdates:
import { unstable_batchedUpdates } from 'react-dom';
// Группировка нескольких setState в один ре-рендер
unstable_batchedUpdates(() => {
setCount(count + 1);
setName('New Name');
setLoading(false);
});2. Автоматический батчинг в обработчиках событий:
// React автоматически батчит обновления в синхронных обработчиках
const handleClick = () => {
setCount(count + 1); // Эти три обновления
setName('New Name'); // будут сгруппированы
setLoading(false); // в один ре-рендер
};3. Проблемы с асинхронным кодом:
// БЕЗ батчинга - несколько ре-рендеров
fetch('/api/data').then(data => {
setLoading(false); // Ре-рендер 1
setData(data); // Ре-рендер 2
setError(null); // Ре-рендер 3
});
// С батчингом - один ре-рендер
fetch('/api/data').then(data => {
unstable_batchedUpdates(() => {
setLoading(false);
setData(data);
setError(null);
});
});React 18 улучшения:
Автоматический батчинг:
// В React 18 все обновления автоматически батчатся
setTimeout(() => {
setCount(count + 1); // Все три обновления
setName('New Name'); // будут сгруппированы
setLoading(false); // автоматически
}, 1000);Кастомные реализации:
// Хук для батчинга в React 17
const useBatchedUpdates = () => {
const batchUpdates = (callback) => {
if (unstable_batchedUpdates) {
unstable_batchedUpdates(callback);
} else {
callback();
}
};
return batchUpdates;
};