Первоначальный рендеринг Гэтсби при ошибке на стороне клиента - PullRequest
0 голосов
/ 08 марта 2020

Итак, я уже некоторое время изучаю эту ошибку и думаю, что дошел до 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, и по-прежнему вызывать повторное рендеринг?

Спасибо за поддержку.

...