Reputation: 9
I have tried to use useEffect to store user details in local storage but unable. Please do any help on it.
Full Code :
const AuthContext = createContext()
const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() =>{
const storedUser = JSON.parse(localStorage.getItem('user'))
setUser(storedUser)
},[])
const login = (userData) => {
localStorage.setItem('user', JSON.stringify(userData));
setUser(userData);
};
const getUser = () => {
return JSON.parse(localStorage.getItem("user"))
}
Upvotes: -1
Views: 90
Reputation: 1954
The following sample code has used the same component of yours, and it found working with this version. Please use the code to check it with yours and find where does the context fail.
The intend of the sample code is just to show how context can be used along with localStorage. The code does not intend to provide a full implementation of login processes.
Notes on the codes, a full listig of code is given below.
a1. The Login component must be enclosed by AuthProvider as below.
<AuthProvider>
<Login />
</AuthProvider>
a2. Inside AuthContext, the children it receives must be enclosed within the provider as below. Please take note that the values for the context is provided here.
<AuthContext.Provider value={{ login, getUser }}>
{children}
</AuthContext.Provider>
b. useContext hook must be used prior to accessing the context object. The following code does the same.
function Login() {
const authContext = useContext(AuthContext);
...
c. The function objects login and getUser have been referenced through the context object as below.
function handleAuthenticate(e) {
...
authContext.login(user);
...
function Login() {
...
const name = authContext.getUser()?.name;
const password = authContext.getUser()?.password;
...
d. The getUser has been suitably modified as below,
const getUser = () => {
// return JSON.parse(localStorage.getItem('user'));
return user;
};
app.js
import { useContext, createContext, useState, useEffect } from 'react';
const AuthContext = createContext();
export default function App() {
return (
<>
<AuthProvider>
<Login />
</AuthProvider>
</>
);
}
function Login() {
const authContext = useContext(AuthContext);
const name = authContext.getUser()?.name;
const password = authContext.getUser()?.password;
const [feedback, setFeedback] = useState(name ? 'Welcome back 🥰' : '');
function handleAuthenticate(e) {
e.preventDefault();
const form = e.target;
const formData = new FormData(form);
const user = Object.fromEntries(formData.entries());
console.log(user);
authContext.login(user);
setFeedback('Logged in 😀');
}
return (
<form method="post" onSubmit={handleAuthenticate}>
<h3>{feedback}</h3>
user name : <input name="name" defaultValue={name}></input>
<br />
Password : <input name="password" defaultValue={password}></input>
<br />
<button type="submit">Login</button>
</form>
);
}
const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() => {
const storedUser = JSON.parse(localStorage.getItem('user'));
setUser(storedUser);
}, []);
const login = (userData) => {
localStorage.setItem('user', JSON.stringify(userData));
setUser(userData);
};
const getUser = () => {
// return JSON.parse(localStorage.getItem('user'));
return user;
};
return (
<AuthContext.Provider value={{ login, getUser }}>
{children}
</AuthContext.Provider>
);
};
Test run
On loading the App.
Getting ready to login
After clicking Login button
After reloading the App.
Upvotes: -1
Reputation: 41
const AuthContext = createContext()
const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() =>{
const storedUser = JSON.parse(localStorage.getItem(`${user}`))
setUser(storedUser)
},[])
const login = (userData) => {
localStorage.setItem(`${user}`, JSON.stringify(userData));
setUser(userData);
};
const getUser = () => {
return JSON.parse(localStorage.getItem(`${user}`))
}
Are you trying to reference the variable? I think you need string interpolation for your "user". I changed it for you in the code above thinking it should work if you're trying to reach that variable. String interpolation is what I normally use when trying to put a variable inside a string using proper syntax ${varName}
inside a ` (it's esc key on the keyboard also known as backticks or grave accents) quotation marks for this to work. It will not work with the other quotation marks, but only that one.
I hope this works.
Upvotes: -1
Reputation: 370
You're utilizing the useState
hook within the useEffect
without any dependencies. Something I noticed at first glance.
Secondly, js prop localStorage
is not always rendered synchronously with the browser so sometimes it can be undefined
My suggestion is to add an if/else statement to perform local storage operations only when it's defined.
Side note: your question needs to be more descriptive.
const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() =>{
const storedUser = JSON.parse(localStorage.getItem('user'))
if (storedUser) {
setUser(storedUser)
} else setUser("noLocalStorage")
},[])
const login = (userData) => {
//if ... else
localStorage.setItem('user', JSON.stringify(userData));
setUser(userData);
};
const getUser = () => {
//if... else
return JSON.parse(localStorage.getItem("user"))
}
Upvotes: -1