Защищенный маршрут продолжает перенаправляться на вход после успешного входа в систему

Я реализую защищенные маршруты в своем приложении React, используя Redux для управления состоянием и React Router для маршрутизации. После успешного входа в систему я могу перейти к защищенным маршрутам. Однако когда я вручную вставляю URL-адрес и пытаюсь перейти к защищенному маршруту (например, video/1245/), меня перенаправляют обратно на страницу входа, даже если я вошел в систему.

Компонент входа:


function Login() {
    const navigate = useNavigate();
    const dispatch = useDispatch();

    const formik = useFormik<formValues>({
        initialValues: {
            email: '',
            password: ''
        },
        validationSchema: loginValidation,
        onSubmit: () => {
            axios.post('/login/', {
                email: formik.values.email,
                password: formik.values.password
            }, {
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            .then((response: AxiosResponse) => {
                if (response.status === 200) {
                    toast.success('Login successful');
                    navigate('/');
                    dispatch(loginUser(response.data.userStatus));
                    try {
                        localStorage.setItem('userInfo', JSON.stringify(response.data));
                    } catch (error) {
                        toast.error('Something went wrong');
                    }
                }
            })
            .catch((error: AxiosError) => {
                toast.error(error.response?.data as string);
            });
        }
    });

    return (
 
    );
}

export default Login;

Компонент защищенной страницы:


const ProtectedPage: React.FC<ProtectedPageProps> = ({ Component }: ProtectedPageProps) => {
    const navigate = useNavigate();
    const { isUserLogin } = useSelector((state: RootState) => state.userAuth);

    useEffect(() => {
        if (!isUserLogin) {
            navigate('/login');
        }
    }, [isUserLogin]);

    return <>{isUserLogin ? Component : null}</>;
};

export default ProtectedPage;

Часть аутентификации пользователя

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

export const userAuthSlice = createSlice({
    name: 'userAuth',
    initialState: {
        isUserLogin: false,
        userStatus: ''
    },
    reducers: {
        loginUser: (state, action: PayloadAction<string>) => {
            state.isUserLogin = true;
            state.userStatus = action.payload;
        },
        logoutUser: (state) => {
            localStorage.clear();
            state.isUserLogin = false;
            state.userStatus = '';
        }
    }
});

export const { loginUser, logoutUser } = userAuthSlice.actions;

export default userAuthSlice.reducer;

Компонент приложения

function App() {
  return (
    <>
      <Navbar />
      <ToastContainer />
      <Routes>
        <Route path='/' element = {<Landing />} />
        <Route path='/login' element = {<Login />} />
        <Route path='/signup' element = {<Signup />} />
        <Route path='/verification' element = {<Verification />} />
        <Route path='/verification-request' element = {<VerificationRequest />} />
        <Route path='/password-reset-request' element = {<PasswordResetRequest />} />
        <Route path='/reset-password' element = {<ResetPassword />} />
        <Route path='/password-reset-verify' element = {<PasswordResetVerify />} />
        <Route path='/upload-video' element = {<UploadVideo />} />
        <Route path='/videos/' element = {<ProtectedPage Component = {<Videos />} />} />
        <Route path='/video/:videoId' element = {<ProtectedPage Component = {<RetriveVideo />} />} />
      </Routes>
    </>
  );
}

export default App;

Проблема: Когда я вручную перехожу к защищенному маршруту после входа в систему, я перенаправляюсь на страницу входа вместо доступа к защищенному маршруту.

Что я пробовал:

  1. Подтверждено, что состояние isUserLogin корректно обновляется после входа в систему.
  2. Убедитесь, что в localStorage задана информация о пользователе после входа в систему.
  3. Проверено, что компонент ProtectedPage правильно проверяет состояние isUserLogin. Что может быть причиной перенаправления на страницу входа при переходе по защищенному маршруту вручную и как решить эту проблему?

Я думаю, что значение состояния сокращения не обновляется

Noob 11.06.2024 05:48
medium.com/@dennisivy/… вы можете передать это
Noob 11.06.2024 05:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
2
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что состояние избыточности не является постоянным: если вы вручную загрузите защищенную страницу, она прочитает исходное состояние, которое вы настроили при создании среза.

Таким образом, решением было бы использовать localStorage вместо просто false в свойстве isUserLogin. Теперь только после входа в систему localStorage будет иметь это значение, поэтому проверка будет постоянной на всех вкладках.

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

export const userAuthSlice = createSlice({
    name: 'userAuth',
    initialState: {
        isUserLogin: Boolean(window.localStorage.getItem('userInfo')), //HERE
        userStatus: ''
    },
    reducers: {
        loginUser: (state, action: PayloadAction<string>) => {
            state.isUserLogin = true;
            state.userStatus = action.payload;
        },
        logoutUser: (state) => {
            localStorage.clear();
            state.isUserLogin = false;
            state.userStatus = '';
        }
    }
});

export const { loginUser, logoutUser } = userAuthSlice.actions;

export default userAuthSlice.reducer;

Другие вопросы по теме

Похожие вопросы

Как реализовать авторизацию на основе ролей в проекте React и ASP.NET Core?
Prime React – Как я могу сделать вновь добавленные строки мгновенно редактируемыми?
Маркеры на ReactMapBoxGl не работают при добавлении слоев GL колоды
Реагируйте: создайте средство просмотра ДНК для очень длинной последовательности
Вкладка Tab внутри диалогового окна Data-Grid MUI закрывает его
Лучший способ получить данные в клиентском компоненте в Next.js 14: useEffect с обработчиками маршрутов и действием асинхронного сервера
Chart.js — ось X не отображает даты с метками времени в формате «ГГГГ-ММ-ДДТЧЧ: мм: сс.СССССС» (Reactchartjs-2)
Какова обычная практика вложения маршрутов в отдельные компоненты в React Router 6?
Как запретить пользователю выходить из полноэкранного режима в следующем js
Redux-toolkit — состояние обновлено, но при его использовании все еще получается начальное значение состояния