score:0

You need to add <Switch> as well. From the documentation:

Renders the first child or that matches the location.

<Switch> is unique in that it renders a route exclusively. In contrast, every <Route> that matches the location renders inclusively.

Just like the following:

<Router>
  <Switch>
     <Navbar isAuth={loggedIn} />
     <Route exact path="/" exact component={Home} />
     <Route path="/login" component={Login} />
     <PrivateRoute path="/dashboard" component={Dashboard} />
  </Switch>
</Router>

Read further here: Router

I hope that helps!

score:0

Your app's state won't update if you change the value of the token in localStorage.

You need to make sure you update the state, I've added a sandbox if it helps.

score:0

Here's how I solved this issue:

To start, I created a isLoggedIn state in my App class. I gave it a componentDidMount() method that would fetch the login state from a cookie on app start. Then I created globalLogin and globalLogout methods as arrow functions, which set the isLoggedIn state to true or false accordingly. I passed my Nav component the isLoggedIn state as a prop and passed the Login and Nav routes the globalLogin and globalLogout methods. These methods can then be called from Login or Nav with this.props.globalLogout(); or this.props.globalLogin();.

This is a simplified version of my App.js.

class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      isLoggedIn: false,
    }
  }
  componentDidMount() {
    const token = Cookie.get("token") ? Cookie.get("token") : null;
    if (token) {
      this.setState({ "isLoggedIn": true });
    }
  }
  globalLogin = () => {
    this.setState({ "isLoggedIn": true });
  }
  globalLogout = () => {
    this.setState({ "isLoggedIn": false });
  }

  render() {
    return (
      <Router>
        <div className="App">
          <Nav isLoggedIn={this.state.isLoggedIn} globalLogout={this.globalLogout}/>
          <Switch>
            <Route path="/" exact component={Home} />
            <Route path="/login" exact>
              <Login globalLogin={this.globalLogin}/>
            </Route>
          </Switch>
        </div>
      </Router>
    );
  }
}

EDIT: using history.push didn't work in login module above so I added an intermediate to handle props

render() {
    const LoginIntermediate = (props) => {
      return (
        <Login {...props} globalLogin={this.globalLogin}/>
      )
    }
    return (
      <Router>
        <div className="App">
          <Nav isLoggedIn={this.state.isLoggedIn} globalLogout={this.globalLogout}/>
          <Switch>
            <Route path="/" exact component={Home} />
            <Route path="/login" exact component={LoginIntermediate} />
          </Switch>
        </div>
      </Router>
    );
  }

score:2

I found a simple solution: use a componentDidMount() or useEffect() function which will render automatically upon loading the NavBar page. Inside this function, use a setInterval() function to continually retrieve the auth status (say, an interval of 5000). This will continually refresh the NavBar, and change the button immediately. I imagine you would have to put the auth check in the NavBar component itself, instead of using props. I put the specific buttons I wanted to change in a separate component called NavBarUser, which changes 'login | signup' to 'logout' and contains a user avatar. I then inserted this component into the NavBar itself at the appropriate place. This is what my code looks like: ``` import React, { useState, useEffect } from 'react'; import Avatar from './Avatar'; import { BrowserRouter as Router, Link } from 'react-router-dom';

const NavBarUser = () => {

    const [user, setUser] = useState({});
    useEffect(() => {
    { /*
        setInterval was used in order to refresh the page constantly
    in order to have the "logout" button show immediately in place of
    "login", as soon as user logs out.
    */}
        setInterval(() => {
            const userString = localStorage.getItem("user");
            const user = JSON.parse(userString);
            setUser(user);
            }, [])
    }, 5000);


    const logout = () => {
        return localStorage.removeItem("user");
    }

    if (!user) {
        return (
            <div className="navbar-nav ml-auto">
                <Link to="/login" className="nav-item nav-link">Login</Link> <span 
className="nav-item nav-link">|</span> <Link to="/SignUp" className="nav-item nav- 
link">Sign Up</Link>
            </div>
        )
    }
    if (user) {
       return (
         <div className="navbar-nav ml-auto">
            <Link to="/" className="nav-item nav-link" onClick={logout}>Logout</Link>
                    <Avatar img="/images/Eat-healthy.jpg" />
            </div>
        )
    }


}


export default NavBarUser;

```

Related Query

More Query from same tag