首页 > 解决方案 > 使用 redux 反应受保护的路由

问题描述

我创建了一个单独node.js restful API的用于检查用户令牌是否有效。我为我的反应保护路线做了这个,即使我的大部分人endpoints已经检查了用户令牌。

我的 redux Thunk:

const verifyToken = () => {
  return async (dispatch: Dispatch) => {
    await axios
      .get("http://localhost:9999/authenticate", {
        headers: { Authorization: `Bearer ${localStorage.getItem("token")}` },
      })
      .then(async (resp) => {
        const { message } = await resp.data;
        console.log(message);
        if (message === "verified") dispatch({ type: "signIn-success" });
      })
      .catch((err) => {
        console.log(err);
        dispatch({ type: "logout-user" });
      });
  };
};

受保护的路线:

const ProtectedRoute: FC<{ children: ReactNode; path: string }> = ({
  children,
  path,
}) => {
  const dispatch = useDispatch(); 
  dispatch(verifyToken()); //dispatch thunk
  const status = useSelector((store: RootStore) => store.status)

  return status && status === "loggedOut" ? (
    <Redirect to="/" />
  ) : (
    <Route path={path} render={() => <>{children}</>} />
  );
};

问题是dispatch我的 thunk 需要时间,因此"/"即使用户令牌检查尚未完成,它也会重定向到。

所以会发生什么,状态的值"loggedOut"首先是然后我的 thunk 将检查令牌是否有效。如果是,状态变为"loggedIn",但为时已晚,因为它已经重定向到"/"

标签: reactjsredux

解决方案


您需要在调度操作时加载,如下所示:


const ProtectedRoute: FC<{ children: ReactNode, path: string }> = ({
  children,
  path,
}) => {
  const [loading, setLoading] = useState(true);

  const dispatch = useDispatch();
  const status = useSelector((store: RootStore) => store.status);

  async function verify() {
    await dispatch(verifyToken()); //dispatch thunk
    setLoading(false);
  }

  useEffect(() => {
    verify();
  }, []);

  if (loading) return <div>Show Loading...</div>;

return status === "loggedOut" ? (
  <Redirect to="/" />
) : (
  <Route path={path} render={() => <>{children}</>} />
);
};

推荐阅读