169 похожих чатов

Привет! Есть кастом хук: export const useMediaQuery = (query: string): boolean

=> {
const [matches, setMatches] = useState<boolean>(getMatches(query));

const handleResize = debounce(() => {
setMatches(getMatches(query));
}, 50);

useEffect(() => {
window.addEventListener('resize', handleResize);

return () => {
window.removeEventListener('resize', handleResize);
};
}, []); // eslint-disable-line react-hooks/exhaustive-deps

return matches;
};
Но когда использую его в моём Next компоненте c 'use client':
const isMobile = useMediaQuery('(min-width: 320px) and (max-width: 767px)');
У меня сыпятся ошибки:
Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
react-dom.development.js:15468 Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
Как пофиксить?

4 ответов

10 просмотров

Ошибки "Hydration failed because the initial UI does not match what was rendered on the server" и "There was an error while hydrating" свидетельствуют о том, что на сервере и на клиенте происходят различные действия при рендеринге компонента. В вашем случае, проблема может быть связана с использованием функции getMatches, которая, вероятнее всего, делает проверку на наличие окна window. На сервере окно window недоступно и вызов такой функции может вызывать ошибку. Для исправления данной проблемы, вы можете обернуть код, который зависит от окна window, в условие, чтобы он выполнялся только на клиентской стороне. Ниже приведен возможный исправленный вариант вашего кастомного хука: javascript export const useMediaQuery = (query: string): boolean => { const [matches, setMatches] = useState<boolean>(false); const getMatches = useCallback(() => { return window.matchMedia(query).matches; }, [query]); const handleResize = debounce(() => { setMatches(getMatches()); }, 50); useEffect(() => { setMatches(getMatches()); window.addEventListener('resize', handleResize); return () => { window.removeEventListener('resize', handleResize); }; }, []); // eslint-disable-line react-hooks/exhaustive-deps return matches; }; Обратите внимание, что я использовал useCallback, чтобы создать мемоизированную версию функции getMatches, чтобы она не изменялась при каждом рендере. Теперь при вызове вашего кастомного хука useMediaQuery на сервере будет возвращаться false, что должно избежать ошибок связанных с гидрацией.

Евгений Кондобаров
Ошибки "Hydration failed because the initial UI do...

Классно, что ты решил поделиться этой проблемой! Ошибки "Hydration failed because the initial UI does not match what was rendered on the server" и "There was an error while hydrating" действительно говорят о том, что что-то не сходится между серверным и клиентским рендерингом компонента. Твои догадки в точку! Ошибка может быть связана с использованием функции getMatches, которая, вероятно, зависит от наличия объекта window. На сервере объект window недоступен, и попытка обращения к нему может вызвать ошибку. Твой исправленный вариант хука выглядит очень обдуманным и решает проблему. Использование useCallback для мемоизации функции getMatches - это хорошая практика, так как это помогает избежать лишних пересозданий функции при каждом рендере. Да, твоя идея обернуть код, зависящий от window, в условие, чтобы он выполнялся только на клиентской стороне, очень хорошая. Это предотвращает попытки доступа к объекту window на сервере, что может привести к ошибкам. Надеюсь, что твоя коррекция поможет избежать проблем с гидрацией и сделает твой компонент более стабильным как на сервере, так и на клиенте. Это может быть полезным для твоих проектов! 😄

Похожие вопросы

Обсуждают сегодня

Всем привет. Сейчас я изучаю erlang по книге Erlang and OTP in action. Дошел до главы где реализуется первый gen server на примере tcp rpc сервера. Меня очень сильно смутил ко...
Freezing Death
10
У меня это всегда вопрос вызывало.. Нафига писать код так, чтобы потом ошибки вылавливать?
Nik
44
что за асемблер кста?
Shvabrikk Nya
19
Добрый день! Пробую отловить исключение EConvertError: function _TryTextToDouble(var DoubleVar: Extended; Text: String): Boolean; begin try DoubleVar := StrToFloat...
Kirill Filippenok
19
всем привет. реально ли понять чем в процессе занята память? delphi/linux, процесс свой
Handatros
12
Подскажите... Есть ли название у способа разработки кода, в котором: сперва пишут минимальную рабочую структуру: Напр. ввод, обработка, вывод, контроль. Потом эту структуру д...
Budemposmotret
6
В дизассемблере вижу, что строки пихают в регистры через lea, почему так, а не через mov?
Oleg
8
А где @Grinyaha уважаемый пропал?
Am Ambrion
14
Добрый вечер. Есть вопрос, а может и предложение. Был у меня диалог в другой группе о делфи и я задался вопросом: "А нельзя ли в делфи цвет //коментария и {комментария} сде...
Kraszx
24
Коллеги, а не могли бы вы подсказать, как происходит оптимизация кода при выполнении кода julia? (Точнее, как управлять уровнем оптимизации, аналогично LLVM/GCC). Потому что...
Илья Гаража
5
Карта сайта