i am using same navbar in multiple components. But when the state changes my navbar showing the changed value in login component only , not in the other components.
Navbar Component
import React, { useEffect } from "react";
import { Link } from "react-router-dom";
import logo from "../CINEPHILE1.png";
function Navbar({login}) {
console.log(login)
useEffect(() => {
console.log(login)
})
return (
<>
<nav className="navbar ">
<div className="container-fluid">
<Link to="/">
<img src={logo} alt="" width="100" height="50" />
</Link>
<Link
to="/cinephile/movies"
className="text-decoration-none text-white "
>
MOVIES
</Link>
<Link
to="/cinephile/tv-shows"
className="text-decoration-none text-white "
>
TV SHOWS
</Link>
{login? (
<Link to ="/cinephile/logout" className="text-decoration-none text-white">
LOG OUT
</Link> )
: (
<>
<Link
to="/cinephile/signup"
className="text-decoration-none text-white "
>
SIGN UP
</Link>
<Link
to="/cinephile/login"
className="text-decoration-none text-white"
>
LOGIN
</Link>
</>
)}
</div>
</nav>
</>
);
}
export default Navbar;
Login Component
import React, { useState } from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { toast } from "react-toastify";
import Navbar from "./Navbar";
function Login() {
const [login,setLogin] =useState(false)
const [email,setEmail] = useState("")
const [password,setPassword] = useState("")
const navigate = useNavigate()
const handleSubmit = async(e) => {
e.preventDefault()
try {
const sendData = await axios.post("http://localhost:5000/cinephile/account/login",{email,password})
if(sendData){
setLogin(true)
navigate("/")
}
} catch (error) {
toast("Invalid Credentials")
}
}
return (
<>
<Navbar login={login}/>
<form onSubmit={handleSubmit}>
<div className="mb-3">
Email address
<input type="email" className="form-control" aria-describedby="emailHelp" onChange={(e)=>setEmail(e.target.value)} required></input>
</div>
<div class="mb-3">
Password
<input type="password" className="form-control" onChange={(e)=>setPassword(e.target.value)} required></input>
</div>
<button type="submit" className="btn btn-primary" >LOGIN</button>
</form>
</>
);
}
export default Login;
Home Component
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import axios from "axios";
import Navbar from "./Navbar";
function Upcoming() {
const [data,setData] = useState([])
const fetchData = async() => {
try {
const getData = await axios.get("https://api.themoviedb.org/3/movie/upcoming",{
params: {language: 'en-US', page: '1'},
headers: {
accept: 'application/json',
Authorization: `${process.env.REACT_APP_API_TOKEN}`
}
})
setData(getData.data.results)
}
catch (error) {
}
}
useEffect(()=>{
fetchData()
},[])
return (
<>
<Navbar/>
<main>
<p className="fst-italic fs-2 text-start text-white">Upcoming</p>
<div className="images_list">
{data.map((value,i)=>(
<div className="images">
<Link to ={`/cinephile/${value.id}`}>
<img src={`https://image.tmdb.org/t/p/w500/${value.poster_path}`} height="300px" alt="" key={i}/>
</Link>
<h4 className="text-white">
{value.original_title}
</h4>
</div>
))
}
</div>
</main>
</>
);
}
export default Upcoming;
Router Component
import React from "react";
import SignUp from "./Signup";
import Navbar from "./Navbar"
import Login from "./Login";
import Upcoming from "./Upcoming";
import UpcomingDetails from "./UpcomingDetails";
import {
Routes,
Route
}
from "react-router-dom";
function Router() {
return(
<>
<Routes>
<Route exact path = "/" element = {<> <Navbar/> <Upcoming/> </>}/>
<Route path = "/cinephile/signup" element={<> <Navbar/> <SignUp/> </>}/>
<Route path = "/cinephile/login" element={<> <Login/> </>}/>
<Route path = "/cinephile/:id" element={<> <Navbar/> <UpcomingDetails/> </>}/>
</Routes>
</>
)
}
export default Router;
All i want is that when a user logins it redirects me to homepage and show the changed navbar but the changed navbar showing only in login component when a user log in i dont know why ?
You're experiencing that problem because you have your login state defined in your Login component. In this situation, only the Login component has access to the login state but not the rest of the pages/routes. That is exactly why your Navbar changes only when you're in the login page. What you should do is to move your login state up to the Route component and pass login
and setLogin
as props to the Login component. That way, all of your components and routes would have access to the login state.
function Login({login, setLogin}) {
const [email,setEmail] = useState("")
const [password,setPassword] = useState("")
const navigate = useNavigate()
const handleSubmit = async(e) => {
e.preventDefault()
try {
const sendData = await axios.post("http://localhost:5000/cinephile/account/login",{email,password})
if(sendData){
setLogin(true)
navigate("/")
}
} catch (error) {
toast("Invalid Credentials")
}
}
return (
<>
<Navbar login={login}/>
<form onSubmit={handleSubmit}>
<div className="mb-3">
Email address
<input type="email" className="form-control" aria-describedby="emailHelp" onChange={(e)=>setEmail(e.target.value)} required></input>
</div>
<div class="mb-3">
Password
<input type="password" className="form-control" onChange={(e)=>setPassword(e.target.value)} required></input>
</div>
<button type="submit" className="btn btn-primary" >LOGIN</button>
</form>
</>
);
}
export default Login;
Router component
import React from "react";
import SignUp from "./Signup";
import Navbar from "./Navbar"
import Login from "./Login";
import Upcoming from "./Upcoming";
import UpcomingDetails from "./UpcomingDetails";
import {
Routes,
Route
}
from "react-router-dom";
function Router() {
const [login, setLogin] = useState(false)
return(
<>
<Routes>
<Route exact path = "/" element = {<> <Navbar login={login /> <Upcoming/> </>}/>
<Route path = "/cinephile/signup" element={<> <Navbar login={login} /> <SignUp/> </>}/>
<Route path = "/cinephile/login" element={<> <Login login={login} setLogin={setLogin} /> </>}/>
<Route path = "/cinephile/:id" element={<> <Navbar login={login} /> <UpcomingDetails/> </>}/>
</Routes>
</>
)
}
export default Router;