AppRoutes:

function AppRoutes(): JSX.Element {
  return (
    <Routes>
      <Route path="/" element={<Auth />} />

      <Route element={<RequiredAuth />}>
        <Route path="/home" element={<Home />} />
      </Route>
    </Routes>
  );
}

私家路由判断

import { Navigate, Outlet } from "react-router-dom";
import useAuth from "./hooks/useAuth";

const RequiredAuth = () => {
  const { user } = useAuth();

  console.log("USERAUTH", user);
  return user ? <Outlet /> : <Navigate to="/" replace />;
};
export default RequiredAuth;

带条件存储的UseAuth Hook

import { create } from "zustand";
import axios, { AxiosResponse } from "axios";
import apiSecure, { api } from "../libs/axios";

type user = {
  id: string;
};

interface useAuthStore {
  user: user | null;
  signIn: (username: string, password: string) => Promise<void>;
  fetchCurrentUser: () => Promise<void>;
}
interface AuthResponse {
  code: number;
  error: boolean;
  message: string;
  data: {
    email: string;
    id: string;
    name: string;
    token: string;
    username: string;
  };
  errors?: [];
}

const useAuth = create<useAuthStore>((set) => ({
  user: null,
  signIn: async (username: string, password: string): Promise<void> => {
    // login process
  },
  fetchCurrentUser: async (): Promise<void> => {
    try {
      const response: AxiosResponse<AuthResponse> = await apiSecure.get(
        `/auth/currentuser`
      );

      const userData = response.data.data;

      set({ user: { id: userData.id } });
      console.log("SETUP", { id: userData.id });
    } catch (error: unknown) {
      // Handle authentication errors
      
    }
  },
}));

export default useAuth;
function App(): JSX.Element {
  const { fetchCurrentUser, user } = useAuth();
  console.log(user);

  useEffect(() => {
    async function auth() {
      await fetchCurrentUser();
    }
    auth();
  }, [fetchCurrentUser]);

  // useEffect(() => {}, [fetchCurrentUser])
  return (
    <>
      <AppRoutes />
    </>
  );
}

export default App;

我正在try 使用REACT-RUTER-V6构建身份验证,并使用zustand进行状态管理,并使用JWT令牌验证用户,其中调用fetchCurrentUser(/auth/currentuserAPI)并使用zustand更新useAuth中的用户状态, 和受保护的路由/home与RequiredAuth,但即使用户验证和状态更新成功,它也是可访问的,或者可以说使用zustand更新的状态在RequidAuth函数中更新.

总是重定向/我做错了什么?

请帮帮忙,我是相对较新的react ,这将是非常感激.提前谢谢!

推荐答案

user状态开始时已经处于"未验证"状态,因此在组件的任何初始呈现中,重定向到"/"都将生效.

有了这样的路由保护和身份验证方案,您实际上有3种"状态":

  • 确认已认证
  • 已确认100已验证
  • 未知,例如"我们还不知道"

重要的是这第三个州.您应该从未知状态开始,等到身份验证确认后再切换到其他两个已确认状态之一.

示例:

interface useAuthStore {
  user?: user | null; // <-- optional to allow undefined

  signIn: (username: string, password: string) => Promise<void>;
  fetchCurrentUser: () => Promise<void>;
}
const useAuth = create<useAuthStore>((set) => ({
  user: undefined, // <-- initially "unknown"

  signIn: async (username: string, password: string): Promise<void> => {
    // login process
  },
  fetchCurrentUser: async (): Promise<void> => {
    try {
      const response: AxiosResponse<AuthResponse> = await apiSecure.get(
        `/auth/currentuser`
      );

      const { data } = response.data;

      if (data.id) {
        set({ user: { id: data.id } });
        console.log("SETUP", { id: data.id });
      } else {
        set({ user: null }); // <-- no id, set null
      }
    } catch (error: unknown) {
      // Handle authentication errors
      set({ user: null }); // <-- auth failed, set null
    }
  },
}));
const RequiredAuth = () => {
  const { user } = useAuth();

  if (user === undefined) {
    return null; // <-- or loading indicator/spinner/etc
  }

  return user ? <Outlet /> : <Navigate to="/" replace />;
};

Reactjs相关问答推荐

如何在重新图表中更改悬停时的条形填充 colored颜色 ?

使用Reaction钩子窗体验证可选字段

for each 子级加载父路由加载器

Reaction路由-如何在布局路由内呈现&q;/:id&q;路由

React 错误无法读取未定义的属性(读取id)#react

尽管所有页面在 Reactjs 中都是公开的,但始终导航到特定页面

标签文本删除了 MUI 概述的输入

无法在react 中向表中添加行

Firebase Storage: 对象不存在图片上传路径错误

React Native应用如何订阅Supabase的实时数据?

如何初始化 redux 全局存储 preloadedState

在准备回调中使用状态属性(Redux 工具包)

如何在同一路由路径上重新渲染组件(链接,V6)reactjs

顶点图表甜甜圈项目边框半径

将 ref 转发到所有页面(路由组件)只是为了将其应用于
并具有跳过导航链接(按钮).有没有更好的办法?

更新和删除功能不工作 Asp.net MVC React

如何解决在 react.js 中找不到模块错误

在 redux 工具包中使用 dispatch 发送多个操作

如何跟踪 dexie UseLiveQuery 是否完成

React中`onScroll`和`onScrollCapture`之间的区别?