根据用户是否登录,在 React 中更改 Navbar 值的正确方法是什么?

Noo*_*oob 7 javascript reactjs

我是 React 的新手,我正在努力了解如何以正确的方式做事。所以我有一个导航栏,它根据用户是否登录显示不同的链接。如果用户登录,我会设置一个 cookie loggedIn=true。比在我的 Navbar 组件中,我使用以下命令检查这些 cookie 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
Run Code Online (Sandbox Code Playgroud)

这是我的应用程序组件:

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;
Run Code Online (Sandbox Code Playgroud)

我觉得这是一种错误的方法,我想获得有关如何正确执行的指示。谢谢!

Apr*_*ion 3

在这种情况下,我建议提升状态:

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>
  );
}
Run Code Online (Sandbox Code Playgroud)

Navbar并在和组件中使用附加属性LogIn(cookie 仅在重新加载页面以达到上述初始状态时使用,而不是在导航栏中使用):

fucntion Navbar(props) {
  return (
    <header>
      ...
      {props.loggedIn ? ... // instead of this.state.loggedIn
  )
}
Run Code Online (Sandbox Code Playgroud)