Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct way to change Navbar values in React based on if user is logged in?

I'm new to React and I'm trying to understand how to do things in the right way. So I have a Navbar that displays different links based on if a user is logged in or not. If a user logs in i set a cookie loggedIn=true. Than in my Navbar component, I check for these cookies with window.setInterval:

import React, { Component } from 'react'
import { NavLink, Link } from "react-router-dom"
import styles from './Navbar.module.css'

class Navbar extends Component {
  constructor() {
    super()

    this.state = {
      loggedIn: false
    }
  }

  componentDidMount() {
    if (document.cookie.split(';').filter((item) => item.trim().startsWith('logedIn=')).length) {
      this.setState({ loggedIn: true })
    }
    window.setInterval(() => {
      if (document.cookie.split(';').filter((item) => item.trim().startsWith('logedIn=')).length) {
        this.setState({ loggedIn: true })
      }
      else {
        this.setState({ loggedIn: false })
      }
    }, 500)
  }

  render() {
    return (
      <header>
        <nav className={` ${styles.navbar} navbar navbar-dark bg-dark navbar-expand-lg`}>
          <div className='container'>
            <Link className='navbar-brand mr-5' to='/'>I <i className={`${styles.red} fas fa-heart fa-xs`}></i> Jokes</Link>
            <button className="navbar-toggler"
              type="button"
              data-toggle="collapse"
              data-target="#navbarContent"
              aria-controls="navbarContent"
              aria-expanded="false"
              aria-label="Toggle navigation">
              <span className="navbar-toggler-icon"></span>
            </button>

            <div className="collapse navbar-collapse" id="navbarContent">
              <ul className="navbar-nav mr-auto">
                <li className="nav-item ">
                  <NavLink className="nav-link" exact to="/">Home</NavLink>
                </li>
                <li className="nav-item">
                  <NavLink className="nav-link" to="/about">About</NavLink>
                </li>
              </ul>
              <ul className="navbar-nav">

                {this.state.loggedIn ?
                  <React.Fragment>
                    <NavLink className="nav-link mr-3" to="/myaccount">My account</NavLink>
                    <NavLink className='nav-link' to='/logout'>Log out</NavLink>
                  </React.Fragment>
                  :
                  <React.Fragment>
                    <NavLink className='nav-link mr-3 ' to='/login'>Log in</NavLink>
                    <NavLink className='nav-link' to='/signup'>Sign up</NavLink>
                  </React.Fragment>
                }
              </ul>
            </div>
          </div>
        </nav>
      </header>
    )
  }
}

export default Navbar

Here is my App component:

import React from 'react'
import { Route, Switch } from 'react-router-dom'

import Navbar from './components/Navbar/Navbar'
import Footer from './components/Footer/Footer'
import Home from './components/Home/Home'
import About from './components/About/About'
import SignUp from './components/SignUp/SignUp'
import LogIn from './components/LogIn/LogIn'
import UserAccount from './components/UserAccount/UserAccount'
import './App.css'

function App() {
  return (
    <div className="App">
      <Navbar />
      <Switch>
        <Route exact path='/about' component={About} />
        <Route exact path='/signup' component={SignUp} />
        <Route exact path='/login' component={LogIn} />
        <Route exact path='/account' component={UserAccount}/>
        <Route exact path='/' component={Home} />
      </Switch>
      <Footer />
    </div>
  );
}

export default App;

I feel like it's a wrong way to do it, and I'd like to get pointers on how to do it properly. Thanks!

like image 256
Noob Avatar asked Jul 27 '19 14:07

Noob


People also ask

How do I change the color of my navbar while scrolling in React JS?

To create the rendering of the background color change of the navbar you will have to create a useEffect where you will pass the changeBackground function and an event listener that will be on scroll and passing the changeBackground function, like so.

How do you highlight an element on navbar depending on scroll in React?

Create forward refs for each of your sections. In your onScroll event handler, create the logic for making a nav item active. Use the previously created refs to access the height properties of your section. Set the active/inactive states of your nav items.


1 Answers

I would recommend Lifting State Up in this case:

function App() {
  const [loggedIn, setLoggedIn] = useState(
    // initial value
    document.cookie.split(';').some((item) => item.trim().startsWith('logedIn=')));

  return (
    <div className="App">
      <Navbar {...{loggedIn}} />
      <Switch>
        <Route exact path='/about' component={About} />
        <Route exact path='/signup' component={SignUp} />
        <Route exact path='/login' render={
          (routeProps) => <LogIn {...{setLoggedIn, ...routeProps}} />
        } />
        <Route exact path='/account' component={UserAccount}/>
        <Route exact path='/' component={Home} />
      </Switch>
      <Footer />
    </div>
  );
}

and use the additional props in Navbar and LogIn components (cookies only used when reloading the page for the initial state above, not inside Navbar):

fucntion Navbar(props) {
  return (
    <header>
      ...
      {props.loggedIn ? ... // instead of this.state.loggedIn
  )
}
like image 188
Aprillion Avatar answered Nov 04 '22 04:11

Aprillion