Reputation: 61
Recently I started using react-bootstrap with nextjs, and when I use the navBar component, it crashes, I don't know why. When my navbar first loads, it is normal,
but, when I refresh the page, the CSS bugs
and this error appears in the console.
Here is my code:
<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>
Does anyone know why this is happening?
Edit: The auth.isLoggedIn
code:
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>
Upvotes: 1
Views: 800
Reputation: 61
as juliomalves said, placing the inititalToken logic inside a useEffect()
hook worked.
Obs: I removed the initial token variable, setting the token directly with the localstorage value (the initial state of the token variable now is "")
useEffect(() => {
setToken(localStorage.getItem("token"));
}, []);
Upvotes: 1