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!
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.
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.
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
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With