【问题标题】:react-bootstrap's navbar bug in NextjsNextjs 中的 react-bootstrap 导航栏标签
【发布时间】:2021-11-01 03:52:21
【问题描述】:

最近我开始使用react-bootstrap和nextjs,当我使用navBar组件时,它崩溃了,我不知道为什么。 我的导航栏第一次加载的时候是正常的,

但是,当我刷新页面时,CSS 错误

这个错误出现在控制台中。

这是我的代码:

<Navbar collapseOnSelect expand="lg" bg="danger" variant="dark">
  <Container>
    <Link href="/" passHref>
      <Navbar.Brand>Tecnologia Única</Navbar.Brand>
    </Link>
    <Navbar.Toggle aria-controls="responsive-navbar-nav" />
    <Navbar.Collapse id="responsive-navbar-nav">
      {auth.isLoggedIn && (
        <>
          <Nav className="me-auto">
            <NavDropdown title="Usuários" id="collasible-nav-dropdown">
              <Link href="/users/" passHref>
                <NavDropdown.Item>Listagem</NavDropdown.Item>
              </Link>
              <Link href="/users/create" passHref>
                <NavDropdown.Item>Novo</NavDropdown.Item>
              </Link>
            </NavDropdown>
          </Nav>
          <Nav className={styles.center}>
            <Navbar.Text>Bem-vindo, {auth.user.name}</Navbar.Text>
            <Nav.Link onClick={logoutHandler}>
              <Button variant="outline-light">Sair</Button>
            </Nav.Link>
          </Nav>
        </>
      )}

      {!auth.isLoggedIn && (
        <Nav>
          <Link href="/login" passHref>
            <Nav.Link>
              <Button variant="outline-light">Entrar</Button>
            </Nav.Link>
          </Link>
        </Nav>
      )}
    </Navbar.Collapse>
  </Container>
</Navbar>

有人知道为什么会这样吗?

编辑:auth.isLoggedIn 代码:

import { createContext, useState, ReactNode } from "react";
import { useRouter } from "next/router";

interface IAuthContext {
  isLoggedIn: boolean;
  token: string | null;
  user: IUserData;
  onLogout: () => void;
  onLogin: (data: LoginData) => void;
}

interface IUserData {
  name: string;
  email: string;
  document: string;
  perfil: number;
}

const AuthContext = createContext<IAuthContext>({
  isLoggedIn: false,
  token: "",
  user: { document: "", email: "", name: "", perfil: 0 },
  onLogout: () => {},
  onLogin: (data: LoginData) => {},
});

type AuthContextProviderProps = {
  children: ReactNode;
};

type LoginData = {
  Id: number | null;
  IsUsuarioAtivo: boolean;
  TipoPerfil: number;
  Token: string;
  Nome: string;
  CPF: string;
  Email: string;
  Login: string | null;
  Perfis: string | null;
  UserIdFB: string | null;
  AccessTokenFB: string | null;
};

export const AuthContextProvider = (props: AuthContextProviderProps) => {
  const router = useRouter();

  let initialToken: string | null = "";
  if (typeof window !== "undefined") {
    initialToken = localStorage.getItem("token");
  }

  const [token, setToken]: any = useState(initialToken);
  const isUserLoggedIn = !!token;

  const [user, setUser]: any = useState<IUserData>({
    document: "",
    email: "",
    name: "",
    perfil: 0,
  });

  const logoutHandler = () => {
    setToken(null);
    localStorage.removeItem("token");
    router.push("/login");
  };

  const loginHandler = (data: LoginData) => {
    console.log(data);
    setToken(data.Token);
    localStorage.setItem("token", data.Token);
    setUser({
      name: data.Nome,
      email: data.Email,
      document: data.CPF,
      perfil: data.TipoPerfil,
    });
    router.push("/");
  };

  return (
    <AuthContext.Provider
      value={{
        user: user,
        token: token,
        isLoggedIn: isUserLoggedIn,
        onLogout: logoutHandler,
        onLogin: loginHandler,
      }}
    >
      {props.children}
    </AuthContext.Provider>
  );
};

export default AuthContext;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

【问题讨论】:

  • 你能显示auth.isLoggedIn来自的代码部分吗?
  • 我编辑了帖子:)
  • 发生不匹配是因为AuthContextProvider 在服务器上执行(设置为空字符串)和客户端上发生再水化(设置为localStorage.getItem("token"))时initialToken 的值不同.尝试将只应在客户端(localStorage 访问)上发生的代码移动到 useEffect 中。
  • 成功了!谢谢

标签: css reactjs next.js react-bootstrap


【解决方案1】:

正如 juliomalves 所说,将 inititalToken 逻辑放在 useEffect() 钩子中是有效的。 obs:我去掉了初始token变量,直接用localstorage值设置token(现在token变量的初始状态是"")

useEffect(() => {
   setToken(localStorage.getItem("token"));
}, []);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多