Назначьте локальное хранилище для реагирования состояния. React Hooks - PullRequest
0 голосов
/ 15 марта 2020

Я пытаюсь войти в систему и обновить свой глобальный контекст данными пользователя. Чтобы сохранить вход пользователя, я храню его данные в локальном хранилище.

Я использую реагирующие хуки, чтобы заботиться о состоянии, поэтому я определил состояние: 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 ( ... );
}

Ответы [ 2 ]

0 голосов
/ 15 марта 2020

Если я понимаю ваш вопрос, вы можете сделать следующее:

const [user, setUser] = useState([], () => {
        const localData = localStorage.getItem('userData');
        return localData ? JSON.parse(localData) : [];
    });
0 голосов
/ 15 марта 2020

Итак, я нашел решение!

В AuthContext. js Мне не нужно было назначать состояние в useEffect. Вместо этого я получаю исходные данные непосредственно при определении хуков состояния:

const localUser = JSON.parse(localStorage.getItem('userData')) || {};
let [userData, setUserData] = useState(localUser);

Таким образом, мне вообще не нужен хук useEffect.

Я надеюсь, что это рекомендуемый способ делать это.

...