Защищенный route через react hooks

Создаю небольшое приложение, понадобилось защищать определенные страницы. Если у пользователя нет валидного token, то перенаправлять его на страницу ввода username/password для получения token. Вот так выглядит мой PrivateRoute компонент:

import React from "react";
import {
  Route,
  Redirect
} from "react-router-dom";
import {
  useSelector,
  useDispatch
} from "react-redux";
import { getCookie } from "../../../lib";
import { tokenCheck } from "../../../actions/userActions";

const PrivateRoute = ({ component: Component, ...rest }) => {

  const dispatch = useDispatch();

  const cookieToken = getCookie("token");
  const stateToken = useSelector((state) => {
    return state.user.token;
  });

  if (!stateToken && cookieToken) {
    dispatch(tokenCheck(cookieToken));
  }

  return (
    <Route
      {...rest}
      render={
        (props) => (
          stateToken ? <Component {...props} /> : <Redirect to="/login" />
        )
      }
    />
  );
}

export default PrivateRoute;

Когда пользователь успешно проходит аутентификацию, я ставлю в браузер cookies такого вида: token=<tokevValue>; expires=<expirationDate> на 1 день для того, чтобы позже, - когда пользователь снова откроет приложение, он мог взять всё ещё валидный token и продолжить работу без необходимости прохождения повторной аутентификации.

Проблема:

Я хочу, чтобы после проверки token, взятого из cookies, и успешно установленного в state, мой PrivateRoute правильно реагировал и рендерил пользователю страницу, которую он запрашивал. Сейчас же, мне всегда рендерится страница логина так как dispatch(tokenCheck(cookieToken)) отрабатывает асинхронно и token попадает в state после того, как произошел рендер PrivateRoute.

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

  1. Пробовал useEffect хук с зависимостью от [stateToken], но это не работает. Если в useSelector() дописать console.log(state.user), и наблюдать, как меняется token, то он, почему-то, всегда пустой. Т.е. useSelector не видит, что токен обновился. Расстановка брейкпоинтов в actions и reducer показывает, что токен-таки обновляется. То же показывает и расширение ReduxDevTools для хрома.
  2. Пробовал сделать свой PrivateRoute компонент async, но тогда получаю ошибку Objects are not valid as a React child (found: [object Promise])

React 17.0.1 Redux 7.2.2

Задачу хочу решить именно хуками.


Ответы (0 шт):