При перезагрузке страницы нужно заново авторизовываться, хотя данные сохранены в localstorage
Возникла проблема, которую не могу решить уже около суток. Задача такая, что при успешной авторизации пользователя, в localstorage должно сохраняться это состояние, чтобы при перезагрузке страницы не нужно было заново авторизовываться. Само состояние сохраняется , но при обновлении страницы все равно требуется повторный вход. Проверьте пожалуйста код, что не так я написал, и что стоит переделать?
SignIn.jsx
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
const SignIn = ({handleAuthSuccess}) => {
const [formData, setFormData] = useState({ nickname: '', pass: '', email: '' });
const [formSubmitted, setFormSubmitted] = useState(false);
const [userData, setUserData] = useState(null);
const [authSuccess, setAuthSuccess] = useState(false);
useEffect(() => {
const auth = JSON.parse(localStorage.getItem('auth'));
if (auth) {
setAuthSuccess(true);
}
}, []);
const handleSubmit = (e) => {
e.preventDefault();
setFormSubmitted(true);
fetch('/api/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
})
.then(res => {
if (!res.ok) {
throw new Error('Ошибка при отправке запроса');
}
return res.json();
})
.then(data => {
if (data.login) {
setAuthSuccess(true);
fetch('/api/userData/' + formData.nickname, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
})
.then(res => res.json())
.then(userData => {
setUserData(userData);
handleAuthSuccess(true, userData);
console.log('Данные пользователя получены:', userData);
})
.catch(error => console.error('Ошибка при получении данных пользователя:', error));
} else {
setAuthSuccess(false);
}
})
.catch(error => {
console.error('Произошла ошибка:', error);
setAuthSuccess(false);
});
};
const handleChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
return (
<div>
<form onSubmit={handleSubmit}>
<label>
Никнейм:
<input type="text" name="nickname" value={formData.nickname} onChange={handleChange} />
</label>
<br />
<label>
Пароль:
<input type="password" name="pass" value={formData.pass} onChange={handleChange} />
</label><br />
<button type="submit">Войти</button>
</form>
{
formSubmitted && (authSuccess ? <p>Пользователь успешно аутентифицирован!</p> : <p>Неправильные данные</p>)
}
</div>
);
};
export default SignIn;
AppRouter.jsx
import React from "react";
import { Routes, Route, useNavigate } from 'react-router-dom';
import SignUp from '../pages/SignUp';
import HomePage from '../pages/HomePage';
import NotFound from '../pages/NotFound';
import SignIn from "../pages/SignIn";
import PersonalAcc from "../pages/PersonalAcc";
import NavBar from "./NavBar";
const publicRoutes = [
{ path: '/', Component: HomePage },
{ path: '/SignUp', Component: SignUp },
{ path: '*', Component: NotFound },
{ path: '/SignIn', Component: SignIn },
];
const authRoutes = [
{ path: '/user', Component: PersonalAcc },
];
const RouteWithProps = ({ path, Component, handleAuthSuccess, ...rest }) => {
return <Component handleAuthSuccess={handleAuthSuccess} {...rest} />;
};
const AppRouter = () => {
const [isAuth, setIsAuth] = React.useState(false);
const [userData, setUserData] = React.useState(null);
const navigate = useNavigate();
const handleAuthSuccess = (isAuthenticated, userData) => {
if (isAuthenticated) {
setUserData(userData);
setIsAuth(true);
navigate('/user');
}
};
return (
<>
<NavBar isAuth={isAuth} userData={userData}/>
<Routes>
{publicRoutes.map(({ path, Component }) => (
<Route key={path} path={path} element={<RouteWithProps Component={Component} handleAuthSuccess={handleAuthSuccess} />} />
))}
{isAuth && authRoutes.map(({ path, Component }) => (
<Route key={path} path={path} element={<RouteWithProps Component={Component} handleAuthSuccess={handleAuthSuccess} userData={userData} />} />
))}
</Routes>
</>
);
};
export default AppRouter;
Ответы (1 шт):
Автор решения: SwaD
→ Ссылка
Вместо хука useEffect
useEffect(() => {
const auth = JSON.parse(localStorage.getItem('auth'));
if (auth) {
setAuthSuccess(true);
}
}, []);
Доставайте значение прямо в момент определения начального состояния
const [authSuccess, setAuthSuccess] = useState(() => {
return JSON.parse(localStorage.getItem('auth')) ? true : false;
});
Или сокращенно
const [authSuccess, setAuthSuccess] = useState(!!JSON.parse(localStorage.getItem('auth')));
Потому что useEffect отрабатывает ПОСЛЕ первого рендера. А на момент первого рендера, переменная authSuccess === false