React - redirect and rerender the navbar after login success

Viewed 1242

when I successfully log in in my REACT app :

  1. sometimes my redirection seems to fail
  2. I need to refresh my page for my navbar to update with username because I just redirect to a component (different from clicking in my navbar)

In Login.js, on login post success, I store loginInformations in localStorage and I ask for a "redirection" :

            .then(response => {
                const loginInformations = {login: this.state.login, loginStatus: "LOGGED_IN"}
                localStorage.setItem("loginInformations", JSON.stringify(loginInformations));

                this.setState({
                    redirection: true,
                });

            })

And in render() method I actually redirect :

    render() {
        const { redirection } = this.state;
        console.log("redirection :", redirection);
        if (redirection) {
            return <Redirect to='/home'/>
        }
        return ()
        ...
    }

Sometimes, this redirection fails (issue number 1). Maybe it is linked to how I "protect" my routes in my navbar : if not logged in, then redirect to /login... Maybe I can not see it, but the redirection is effective and the localStorage has not been updated before the navbar rendering so the navbar redirects to the login component giving me the impression that the page did not change...

export default class myNav extends React.Component {
    constructor(props) {
        super(props);

        let loginInformations = {
            login: "unknown user",
            loginStatus: "NOT_LOGGED_IN"
        }
        if (localStorage.getItem("loginInformations")) {
            loginInformations = JSON.parse(localStorage.getItem("loginInformations"));
        }
        this.state = {
            login: loginInformations.login,
            loginStatus: loginInformations.loginStatus,
        };
    }

    render() {

        const loggedIn = (this.state.loginStatus === "LOGGED_IN");
        const redirToLogin = <Redirect to='/login' />;

        return (
            <Router>
                <div>
                    <Navbar bg="dark" variant="dark" className="myNav">
                        {   
                            loggedIn ? 
                            <Navbar.Brand href="/">{this.state.login}'s blog</Navbar.Brand> :
                            <Navbar.Brand href="/">Blog</Navbar.Brand>
                        }
                        <Nav className="mr-auto">
                            <Nav.Link href="/home">Home</Nav.Link>
                            {   
                                loggedIn ? 
                                <Nav.Link href="/logout">Logout</Nav.Link> : 
                                <Nav.Link href="/login">Login</Nav.Link>
                            }
                        </Nav>
                    </Navbar>

                    <Switch>
                        <Route path="/login" />
                            <Login />
                        </Route>

                        <Route path={["/home", "/"]}>
                            {loggedIn ? <Home /> : redirToLogin }
                        </Route>

                    </Switch>
                </div>
            </Router>
        );
    }

And obviously, as I redirect to my Login component, the navbar does not rerender with the username (issue number 2).

Bonus question : how could I make an if statement inside the return before calling my Routes (only the ternary works but if I had many Routes I would have to use many ternaries) ? This doesn't help me to do this as I would like to do.


{/* ========== PROTECTED ROUTE : THE FOLLOWING DOES NOT WORK ========== */}
{/* {() => {
        if (!loggedIn) {
            return redirToLogin
        }
    }
} */}

<Route path={["/home", "/"]}>
   {loggedIn ? <Home /> : redirToLogin }
</Route>

Thank you very much for your time.

0 Answers
Related