Перейти к содержимому

← Все статьиСайты и SEO

· ~1 мин чтения ·

React #185: бесконечный ререндер из-за useSyncExternalStore и как его исправить

Минифицированная ошибка React #185 расшифровывается как «Maximum update depth exceeded»: компонент бесконечно перерисовывается, и React в какой-то момент прерывает работу. Страница при этом падает целиком. Я встретил её на собственном сайте, когда выносил состояние (тему оформления, выбор cookie, значения из localStorage) в отдельное внешнее хранилище.

Как работает useSyncExternalStore

Хук принимает функцию подписки и функцию getSnapshot, которая возвращает текущее значение. React вызывает getSnapshot часто и сравнивает результаты между вызовами через Object.is. Если два подряд идущих вызова вернули разные значения, React решает, что хранилище изменилось, и запускает новую отрисовку.

Где возникает ловушка

Если getSnapshot каждый раз строит новый объект или массив — например, разбирает JSON из localStorage и возвращает свежий {...} — то два вызова подряд вернут разные ссылки, даже когда данные одинаковы. React видит «изменение», перерисовывается, снова вызывает функцию, снова получает новую ссылку — и так до тех пор, пока не сработает защита от бесконечного цикла.

Как это исправить

Снимок должен быть стабильным: пока данные не изменились, функция возвращает ровно то же значение. Самое надёжное — хранить в снимке примитив, например строку, а разбирать её уже в компоненте. Так я сделал для согласия на cookie: в localStorage лежит строка, getSnapshot возвращает эту строку, и сравнение Object.is работает как надо. Если нужен объект, кэшируйте его и пересоздавайте только при реальном изменении данных. Отдельно задайте getServerSnapshot, чтобы сервер и первая отрисовка в браузере совпадали.

Урок: не списывайте ошибку на тесты

Сначала я принял эту ошибку за артефакт прокрутки в автотестах и потерял время. Любую ошибку #185 нужно считать настоящей, пока не доказано обратное: она означает реальный цикл отрисовки, который у пользователя может проявиться на слабом устройстве. Если при разработке сайта вам нужна такая внимательность к деталям, это часть разработки сайтов под ключ.

Связанные услуги

Читайте также

Ещё по теме «Сайты и SEO»

← Все статьи блога · Кейсы