最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to update NavBar component in React upon successful log-in and before logging in - Stack Overflow

programmeradmin3浏览0评论

I am trying to modify the Navbar contents before and after logging in so that before logging in, it shows Login and Register and after logging in, it shows other tabs apart from those two. I have an Auth.js with a function called isAuthenticated() which returns true if the user is logged in or false otherwise. Initially, isAuthenticated() returns false, so the Navbar shows register and login. However, once the user logs in, isAuthenticated() bees true but that is not reflected in Navbar. How can I change that to ensure that it shows different things upon login/logout.

PS - I havent pleted navigation but I can conditionally render it to show different things if isLoggedin is true or false.

App.js

import ProtectedRoute from './protectedroute'
import Auth from './Auth'

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
     const isAuthenticated = Auth.isAuthenticated() 
     console.log(isAuthenticated)
  return (
      <Router>
        <div>
          <NavigationBar isLoggedin={isAuthenticated}/>
          <Switch>
            <Route exact path = '/'
              ponent = {LandingPage}
            />
            <Route exact path = '/register'
              ponent = {Register}
            />
            <ProtectedRoute exact path = '/Success' 
              ponent = {Success}
            />
            <Route path="*" ponent = {() => "404 NOT FOUND"}/>
          </Switch>
        </div>
      </Router>
  );
}
}

export default App;

Auth.js

class Auth {
    constructor() {
        this.authenticated = false;
    }

    login() {
        this.authenticated = true;
    }

    logout() {
        this.authenticated = false;
    }

    isAuthenticated() {
        return this.authenticated;
    }
}

export default new Auth();

NavigationBar.js

import React from 'react'
import { Button, Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
import { Link } from 'react-router-dom'


class NavigationBar extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    const isLoggedin = this.props.isLoggedin
    console.log(isLoggedin)
    return (
      <Navbar expand="lg">
        <Navbar.Brand >hello</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="ml-auto">
            <Nav.Link><Link to='/'>Login</Link></Nav.Link>
            <Nav.Link><Link to='/register'>Register</Link></Nav.Link>
          </Nav>
        </Navbar.Collapse>
      </Navbar>
    )
  }
}

export default NavigationBar

I am trying to modify the Navbar contents before and after logging in so that before logging in, it shows Login and Register and after logging in, it shows other tabs apart from those two. I have an Auth.js with a function called isAuthenticated() which returns true if the user is logged in or false otherwise. Initially, isAuthenticated() returns false, so the Navbar shows register and login. However, once the user logs in, isAuthenticated() bees true but that is not reflected in Navbar. How can I change that to ensure that it shows different things upon login/logout.

PS - I havent pleted navigation but I can conditionally render it to show different things if isLoggedin is true or false.

App.js

import ProtectedRoute from './protectedroute'
import Auth from './Auth'

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
     const isAuthenticated = Auth.isAuthenticated() 
     console.log(isAuthenticated)
  return (
      <Router>
        <div>
          <NavigationBar isLoggedin={isAuthenticated}/>
          <Switch>
            <Route exact path = '/'
              ponent = {LandingPage}
            />
            <Route exact path = '/register'
              ponent = {Register}
            />
            <ProtectedRoute exact path = '/Success' 
              ponent = {Success}
            />
            <Route path="*" ponent = {() => "404 NOT FOUND"}/>
          </Switch>
        </div>
      </Router>
  );
}
}

export default App;

Auth.js

class Auth {
    constructor() {
        this.authenticated = false;
    }

    login() {
        this.authenticated = true;
    }

    logout() {
        this.authenticated = false;
    }

    isAuthenticated() {
        return this.authenticated;
    }
}

export default new Auth();

NavigationBar.js

import React from 'react'
import { Button, Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
import { Link } from 'react-router-dom'


class NavigationBar extends React.Component {

  constructor(props) {
    super(props);
  }

  render() {
    const isLoggedin = this.props.isLoggedin
    console.log(isLoggedin)
    return (
      <Navbar expand="lg">
        <Navbar.Brand >hello</Navbar.Brand>
        <Navbar.Toggle aria-controls="basic-navbar-nav" />
        <Navbar.Collapse id="basic-navbar-nav">
          <Nav className="ml-auto">
            <Nav.Link><Link to='/'>Login</Link></Nav.Link>
            <Nav.Link><Link to='/register'>Register</Link></Nav.Link>
          </Nav>
        </Navbar.Collapse>
      </Navbar>
    )
  }
}

export default NavigationBar
Share Improve this question asked May 31, 2020 at 6:21 xyz6675xyz6675 3652 gold badges7 silver badges18 bronze badges 4
  • You will need to conditionally render the items just like you mentioned in your postscript. – Nafiz Ahmed Commented May 31, 2020 at 6:36
  • However, isLoggedIn does not change its value from false to true. It remains false everytime. – xyz6675 Commented May 31, 2020 at 6:39
  • It is because your app ponent does not render with changes to authentication. A react ponent will rerender only if there is a change in its state or props. And your isAuthenticated does not satisfy either one of those and thus, the changes in navbar do not get reflected. – Nafiz Ahmed Commented May 31, 2020 at 9:29
  • How can I bat that? I need to do it – xyz6675 Commented May 31, 2020 at 19:31
Add a ment  | 

1 Answer 1

Reset to default 3

First, you will need to render your navbar based on your session. i.e. If there is a change in a session like a user is logged in or logged out, the navbar needs to render.

For simplicity, to acplish the above task, we will keep the isAuthenticated as an App state property and will pass the isAuthenticated as a prop of NavigationBar. Now any change of isAuthenticated will result in a render of the NavigationBar ponent.

Code example, in App.js:

constructor(props) {
  super(props);
  this.state = { isAuthenticated: false };
}

render() {
  const { isAuthenticated } = this.state;
  .
  .
  .

instead

const isAuthenticated = Auth.isAuthenticated()

Now, since we removed the Auth.js file and we do require methods like login and logout, we will add such methods in the App ponent.

Example:

class App extends React.Component {
  constructor(props) {
    super(props);
  }

  login = () => {
    this.setState({ isAuthenticated: true });
  }

  logout = () => {
    this.setState({ isAuthenticated: false });
  }

  render() { ...

And we will need to call these methods depending on the user's activity. Like if a user signs in successfully, we will call the login method. Now, it is important to note that you need to pass these methods as props to child ponents who will call these. For example, your NavigationBar may need to call the logout and so you pass the method like

<NavigationBar isLoggedin={isAuthenticated} logout={this.logout}/>

Finally, now, based on isLoggedin in NavigationBar, you can render the conditional items.

For example, in NavigationBar.js file,

<Nav className="ml-auto">
  {isLoggedin && (<Nav.Link><Link to='/logout'>Logout</Link></Nav.Link>)}
  {!isLoggedin && (<Nav.Link><Link to='/'>Login</Link></Nav.Link>)}
  {!isLoggedin && (<Nav.Link><Link to='/register'>Register</Link></Nav.Link>)}
</Nav>

The above code will render login and register items if a user is not signed in and vice versa.

Now, all through the walkthrough, we start and maintain the user session in the react ponent state only. This is not ideal since whenever a user refreshes the page, the session will be lost. To mitigate the issue, you will need to use local storage or any other approach that you may find suitable.

发布评论

评论列表(0)

  1. 暂无评论