将本地存储分配给反应状态。反应钩

时间:2020-03-14 23:46:36

标签: reactjs authentication local-storage token react-hooks

我正在尝试登录用户,并使用用户数据更新全局上下文。为了使用户保持登录状态,我将其数据存储在本地存储中。

我正在使用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 ( ... );
}

3 个答案:

答案 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')));