我正在尝试登录用户,并使用用户数据更新全局上下文。为了使用户保持登录状态,我将其数据存储在本地存储中。
我正在使用react-hooks来处理状态,因此我定义了一个状态:let [userData, setUserData] = useState({});
。
由于我不想让用户保持登录状态,因此我在登录期间将其数据存储在本地存储中。此方法有效,并且数据确实存储在本地存储中。
但是,我的问题是我无法将初始userData
状态设置为等于本地存储中的当前数据。换句话说,userData
状态会在重新加载时重置为默认值。
我认为可以从本地存储中获取初始数据并将其分配给useEffect
挂钩内的状态。但是在setUserData
内部调用useEffect
时,状态不会更新。
AuthContext.js:
import React, { createContext, useState, useEffect } from 'react';
export const AuthContext = createContext();
const AuthContextProvider = props => {
let [userData, setUserData] = useState({});
const loginUser = (data) => {
localStorage.setItem('userData', JSON.stringify({
key: data.key,
id: data.id,
email: data.email,
first_name: data.first_name,
last_name: data.last_name
})); // Save the user object in local storage
setUserData({
key: data.key,
id: data.id,
email: data.email,
first_name: data.first_name,
last_name: data.last_name
}); // Set user data
};
const logoutUser = () => {
localStorage.removeItem('userData');
setUserData({}); // Empty user data state
newToast('Successfully signed out');
};
useEffect(() => {
const localUser = JSON.parse(localStorage.getItem('userData'));
if (localUser && localUser.key) {
setUserData({
key: localUser.key,
id: localUser.id,
email: localUser.email,
first_name: localUser.first_name,
last_name: localUser.last_name
}); // Set user data
}
}, [])
return (
<AuthContext.Provider value={{ userData, loginUser, logoutUser, newToast }}>
{props.children}
</AuthContext.Provider>
)
}
export default AuthContextProvider;
Signin.js:
const Signin = props => {
let [loading, setLoading] = useState(false);
let [formError, setFormError] = useState(false);
const { userData, loginUser, newToast } = useContext(AuthContext);
const { register, handleSubmit, errors, setError, clearError } = useForm();
const onSubmit = e => {
setLoading(true);
setFormError(false);
clearError(); // Clear all erros on form
axios
.post('users/auth/login/', {
headers: { 'Content-Type': 'application/json' },
email: `${e.email}`,
password: `${e.password}`,
})
.then(res => {
const { data } = res
loginUser(data);
newToast('Successfully signed in');
})
.catch((error) => {
const { data } = error.response;
console.log(data);
data.email && setError("email", "", data.email);
data.password1 && setError("password", "", data.password1);
setFormError(true);
})
setLoading(false);
};
return ( ... );
}
答案 0 :(得分:4)
所以我想出了一个解决方案!
在AuthContext.js中,我不需要在useEffect
中分配状态。
而是在定义状态挂钩时直接获取初始数据:
const localUser = JSON.parse(localStorage.getItem('userData')) || {};
let [userData, setUserData] = useState(localUser);
那样,我根本不需要useEffect
钩子。
我希望这是推荐的方法。
答案 1 :(得分:1)
如果我了解您的问题,则可以执行以下操作:
const [user, setUser] = useState([], () => {
const localData = localStorage.getItem('userData');
return localData ? JSON.parse(localData) : [];
});
答案 2 :(得分:0)
如何像这样使用useReducer?
US presidential debate LIVE: Trump making friends with ‘thugs’ like Putin and Kim, says Biden
To buy or not to buy: Why BJP’s Bihar move comes as a surprise to states
Two terrorists surrender after families brought to encounter site in Jammu and Kashmir`s Baramulla
Fire breaks out at City Centre mall in Mumbai
After teacher’s killing, French Muslims fear rising Islamophobia
To buy or not to buy: Why BJP’s Bihar move comes as a surprise to states
Delhi's air quality dips, morning walkers irked
55,839 Fresh Coronavirus Cases In India, Total Cases At 77.06 Lakh: 10 Points
After Bihar, Tamil Nadu, Madhya Pradesh Promise Free Vaccine: 10 Points
US presidential debate LIVE: Trump making friends with ‘thugs’ like Putin and Kim, says Biden
COVID-19 vaccine may be ready by December. Trials to safety — a look at India's vaccine journey
US Elections 2020 HIGHLIGHTS: Intelligence agencies say Iran, Russia have tried to meddle in polls
Trump-allied groups pour $30 million into Barrett’s confirmation to Supreme Court
您可以打电话
const [user, setUser] = useReducer((prev, cur) => {
localStorage.setItem('userData', JSON.stringify(cur));
return cur;
}, JSON.parse(localStorage.getItem('userData')));