Итак, я уже некоторое время изучаю эту ошибку и думаю, что дошел до root причины. У меня есть навигационная панель, которая меняется, если пользователь вошел в систему или нет. При рендеринге сервера (я использую gatsby) это свойство, очевидно, всегда ложно, что означает, что я получу гостевую навигационную панель с сервера при первоначальном рендеринге.
У меня есть следующий хук для проверки isLoggedIn:
import { useContext, useState, useEffect } from 'react';
import { UserContext } from '../contexts/UserContext';
import { isAuthenticated } from '../services/pilates-studio/localstorage';
const useIsLoggedIn = () => {
const { user } = useContext(UserContext);
const [isLoggedIn, setIsLoggedIn] = useState(isAuthenticated);
useEffect(() => {
console.log('we update isLoggedIn');
setIsLoggedIn(!!user || isAuthenticated);
}, [user]);
return isLoggedIn;
};
export default useIsLoggedIn;
isAuthenticated
извлекает токен доступа из localStorage, поэтому, как только мы выполним гидратацию приложения на клиенте и пользователь уже вошел в систему, isAuthenticated
приведет к true
.
Таким образом, первое состояние isLoggedIn на стороне клиента будет истинным. Таким образом, мы получаем гостевую навигационную панель с сервера, но поскольку состояние не меняется, мы не переопределяем навигационную панель, хотя технически состояние навигационной панели isLoggedIn изменилось.
Моя панель навигации:
const NavBarContainer = () => {
const isLoggedIn = useIsLoggedIn();
return (
<NavBar logo={Logo} menu={NavMenu} isMenuOpen={isMenuOpen}>
<NavBarItem key="courses" label="Kurse" link={isLoggedIn ? '/courses' : '/courses/starter'} />
<NavBarItem key="appointment" label="Termine" link="/appointment" show={isLoggedIn} />
<NavBarItem key="trainers" label="Trainer" link="/trainers" />
<NavBarItem key="login" label="Login" link="/login" show={!isLoggedIn} floatRight />
<NavMenuButton key="menu" label="Menu" onClick={handleMenuClicked} icon={<UserIcon />} show={isLoggedIn} floatRight />
</NavBar>
);
};
export default NavBarContainer;
Если я изменю исходное состояние моего крючка на
const [isLoggedIn, setIsLoggedIn] = useState(false);
, я получу его для повторного отображения, но теперь у меня есть панель навигации, которая " мигает "/" мерцает "при начальной загрузке, так как он перерисовывается от гостя до входа в navbar в секунду. Я хотел бы избежать этого мерцания.
Я совсем новичок в SSR и Гэтсби. Как бы вы решили мерцание? Как я могу иметь начальное состояние isLoggedIn, установленное в true, и по-прежнему вызывать повторное рендеринг?
Спасибо за поддержку.