ユーザーにサインインして、グローバルコンテキストをユーザーデータで更新しようとしています。ユーザーのサインインを維持するために、ローカルストレージにデータを保存しています。
私は状態を処理するためにreact-hookを使用しているので、状態を定義しました: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 ( ... );
}
だから私は解決策を見つけました!
AuthContext.jsでは、で状態を割り当てる必要はありませんでしたuseEffect
。代わりに、状態フックを定義するときに初期データを直接取得します。
const localUser = JSON.parse(localStorage.getItem('userData')) || {};
let [userData, setUserData] = useState(localUser);
そうすれば、useEffect
フックはまったく必要ありません。
これが推奨される方法であることを願っています。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加