0

So I understand how to create the individual components like the form, navbar and footer but what I don't understand is how to change the state of the navbar when the user signs out.

For example, the login-in page should have a form with a very basic navbar and a couple of navLinks, but once the user is logged in, the navbar should include "signout" nav links and a footer with a couple of nav links as well.

The problem I have when I do mine is that when I click the "sign-out" link, it does render the login page BUT when I click one of the other navlinks, the navbar rerenders the "logged in" version.

CustomNavbar.js

import React, { Component } from 'react'
import { Navbar, Nav, NavItem } from 'react-bootstrap';

class CustomNavbar extends Component {

render() {
    if (this.props.userID === null) {
        return (
            <div>
                <Navbar collapseOnSelect expand="md" bg="dark" variant="dark">
                    <Navbar.Brand href="/">
                        Ndnu's Notes
                    </Navbar.Brand>
                    <Navbar.Toggle aria-controls="responsive-navbar-nav" />
                    <Navbar.Collapse id="responsive-navbar-nav">
                    </Navbar.Collapse>
                </Navbar>
                <Navbar className="footer text-center" fixed="bottom" expand="lg" bg="light">
                    <Nav.Link href="/contactus">Contact Us</Nav.Link>
                    <Nav.Link href="/privacyterms">Privacy & Terms</Nav.Link>
                    <Nav.Link href="/about">About</Nav.Link>
                </Navbar>
            </div>
        )
    } else {    
        return (
            <div>
                <Navbar collapseOnSelect expand="md" bg="dark" variant="dark">
                    <Navbar.Brand href="/">
                    Ndnu's Notes
                </Navbar.Brand>
                <Navbar.Toggle aria-controls="responsive-navbar-nav" />
                    <Navbar.Collapse id="responsive-navbar-nav">
                        <Nav className="mr-auto">
                        </Nav>
                        <Nav>
                            <Nav.Link eventKey={2} href="/myAccount"> <i class="fas fa-user"></i> My Account</Nav.Link>
                            <Nav.Link eventKey={1} href="/" onClick={this.props.logUserOut}> <i class="fas fa-sign-out-alt"></i> Log Out</Nav.Link>
                        </Nav>
                    </Navbar.Collapse>
                </Navbar>

                {/* Footer */}
                <Navbar fixed="bottom" bg="light">
                    <Nav.Link href="/contactus">Contact Us</Nav.Link>
                    <Nav.Link href="/privacyterms">Privacy & Terms</Nav.Link>
                    <Nav.Link href="/about">About</Nav.Link>
                </Navbar>
            </div>
        )
    }
}
}
export default CustomNavbar

App.js

import React from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import LoginAndRegister from './LoginAndRegister'
import ContactUs from './Components/ContactUs.js';
import PrivacyTerms from './Components/PrivacyTerms.js';
import CustomNavbar from './Components/CustomNavbar.js';
import About from './Components/About.js';
import Table from './Components/Table.js';

class App extends React.Component {


constructor() {
    super();
    this.state = {
        userID:
    }
}
logUserOut = (e) => {
    e.preventDefault()
    this.setState({userID: null});
}

render() {
    return (
        <Router>
            <div>
                <CustomNavbar userID={this.state.userID} logUserOut={this.logUserOut} />
                <Route exact strict path="/contactus" component={ContactUs} />
                <Route exact strict path="/about" component={About} />
                <Route exact strict path="/privacyterms" component={PrivacyTerms} />
                  {!this.state.userID && <LoginAndRegister userID={this.state.userID}/>}
                <Table />
            </div>
        </Router>
    )
}
}

export default App;
UsernameNotFound
  • 115
  • 2
  • 3
  • 8

1 Answers1

0

Up until this point, it doesn't look like you have any code that checks upon page load if your user is already logged in (by checking a cookie or asking the server or anything like that). That means that, every time your page loads your login state will correspond to whatever you set for your initial state. You do this in your App constructor:

this.state = {
  userID: 123 // you mentioned in your comments that this is what you used
}

So, when the page initially loads, here is what happens:

  1. App constructor is called, and the initial state is set with userID: 123. So, the page is loaded with User 123 already logged in. This is why you see a navbar with a "My Account" and "Log Out" available.

  2. You click on "Log Out". This correctly sets the userID to null. You are logged out. You no longer have "My Account" or "Log Out" available to you in your navbar.

  3. You click on one of the other nav links, for example "Contact Us". A new page is loaded. Everything starts all over again.

  4. App constructor is called again, and the initial state is again set back to userID: 123. Your user is logged in.

To fix this, you can start by setting userID: null in your contructor. This way, with every new page load, the user begins logged out. But also, eventually, you will probably need to build in code that maintains (on the client's browser) some sort of cookie that tells your site that a user is logged in, and maintains that state from one page load to the next.

I've created a code sandbox which uses the code you've provided, but then added some modifications to help demonstrate what I've explained above. In this sandbox, the user begins logged out. When you click on a button to simulate login, then the user is logged in. But, if you click on a navbar link that takes you to another page, then you'll see that the user is logged out again.


Separately, you should note that some of your JSX code (in particular, the <i> tags in CustomNavbar.js) are using a prop class - these should be changed to className, or else React will complain.

Alvin S. Lee
  • 4,984
  • 30
  • 34