I have a signup page in react wherein after signup ,the user is redirected to the homepage.I want to make my homepage a protected route where only loggedin users can enter.
My code for signup:
const navigate = useNavigate();
const handleSignup = (e) => {
e.preventDefault();
const email = document.querySelector('#email').value;
const password = document.querySelector('#password').value;
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
console.log(user);
setcurrentuser(user);
setTimeout(()=>{
navigate('/homepage');
},3000);
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
// ..
});
}
after receiving user object from firebase, I have set the state for the user and as state takes time to get updated,I have used a timeout of 3s to navigate to the homepage.Still when I log the user object I get undefined.
Code for homepage:
const Homepage = ({user,username,setusername}) => {
console.log(user);
const navigate=useNavigate();
// useEffect(()=>{
// if(user=={} || !user)
// navigate('/signup');
// })
return(
<>
...some code here
</>)}
export default HomePage
The state is in the app component and signup component sets the state for the user object using the props it receives. Homepage gets the props from the app component.
CodePudding user response:
The best way to this, to use useContext instead of props. As its easier and more efficient. Here is a link to a documentation to help you out. Visit https://betterprogramming.pub/react-hooks-and-forms-dedb8072763a
CodePudding user response:
Okey,
first of all inorder not to get undefined or null on that protected Homepage
you need some way of accessing a user data, those obtained after login,
and primary good place to store those so they'll be accessible across the entire site is on localStorage
with this code and once you navigate to Homepage
you'll go to take your stored user on your localStorage
Note1: localStorage
store primitive data with no problem, but objects needs to be stringified first, we'll get to that soon,
Note2: waiting 3 seconds to navigate to another page is awful alot of time in user experience, i wont suggest that, if you want to wait for some event to occur so as to trigger another event and you dont have other way, you can use javascript's
event loop trick of zero second which places the function/event needed to wait on just nextTick
of event loop. which is done by writing
setTimeout(()=>{
navigate('/homepage');
},0); //Note that 0 second, that will place navigation on nextTick of eventLoop
Now if Note2 is confusing just dont worry, lets get to your problem,
Signup:
const navigate = useNavigate();
const handleSignup = (e) => {
e.preventDefault();
const email = document.querySelector('#email').value;
const password = document.querySelector('#password').value;
createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
// Signed in
const user = userCredential.user;
console.log(user);
//Edited place
if(user){ //check if we got user object right
localStorage.setItem('user',JSON.stringify(user));//store in global storage
navigate('/homepage');//let go to homepage :)
}//End of Edited
})
.catch((error) => {
const errorCode = error.code;
const errorMessage = error.message;
// ..
});
}
Right on Homepage area
const Homepage = () => {
//console.log(user);This wont give you your user so just remove it from the props above
const navigate=useNavigate();
useEffect(()=>{
let user = localStorage.getItem('user');
if(user){
//then we have user
//bring her up from object stringifying..
user = JSON.parse(user);
//get her details if needed
const {username, email,...} = user
}else{ //not signed so go back
navigate('/signup');
}
})
return(
<>
...some code here
</>)
}
export default HomePage