最近想摸一个简单的管理后台页面,前端登录这块一开始是参考的 react-router 官方的一个示例
想要实现一个如果请求 statusCode 是 4xx 的话就重新跳转到登录页的功能,考虑使用 react-router 的errorElement捕获 error 实现,为此需要使用 v6.4 加入的 createBrowserRouter
来创建路由,把官方示例中 App.tsx 路由申明部分改成了这样:
const router = createBrowserRouter(
createRoutesFromElements(
<Route element={<Layout />}>
<Route path="/" element={<PublicPage />} />
<Route path="/login" element={<LoginPage />} />
<Route
path="/protected"
element={
<RequireAuth>
<ProtectedPage />
</RequireAuth>
}
/>
</Route>
)
);
return (
<AuthProvider>
<RouterProvider router={router} />
<AuthProvider/>
);
并去掉了 main.tsx 中的 <BrowserRouter><BrowserRouter/>
随后运行示例就发现了一个诡异的问题:
登录第一次成功后它不能跳转到 /protected
下,原因是被 RequireAuth
组件给拦住了,跳转回了 /login
,需要点两次登录才能顺利跳转,可是明明在 signin
的回调中 setUser(newUser)
了,这个现象在原本用了 <BrowserRouter>
的示例中没有出现,一使用 createBrowserRouter
就会这样。
翻了两天文档还是毫无头绪,望前端大佬不吝赐教。
1
morri 2023-01-13 18:31:44 +08:00 2
直接快进到 https://nextjs.org/ 吧
使用 https://swr.vercel.app/zh-CN hook 。我最近也在研究,nextjs 的好处还在于可以服务端渲染你想要渲染的页面。 |
2
christin 2023-01-13 18:40:08 +08:00 via iPhone
<Route path="/login" element={<LoginPage />} />
<Route path="/protected" element={ <RequireAuth> <ProtectedPage /> </RequireAuth> } /> 把 login 放到 protected 下面试一下 |
3
Jarvis666 2023-01-14 18:57:43 +08:00
能给一个复现的代码仓库吗?我最近也在看 auth 这个例子😀
|
4
randomstream 2023-01-14 20:27:13 +08:00
不知道啥情况,但是将状态使用变量定义在组件外面就不会出现问题,不知道是不是 useState 更新是异步和 react-router 之间的问题还是啥的。。
|
5
Akitora OP @Jarvis666 复现 https://stackblitz.com/edit/github-cnzc4l-gjsber?file=src/main.tsx
@randomstream 确实是这样的感觉!像是状态更新慢了一拍一样。找到的唯一一个能用的示例它保存状态使用的是 localStorage… @christin 这样 login 都访问不了了吧… |
6
Jarvis666 2023-01-15 13:22:07 +08:00 1
可以在 setUser(newUser) 打印一下 newUser ,第一次打印出来的 user 为 null ,第二次打印出来的 user 是第一次输入的 username ,可以通过输入两次输入不同的值来验证。
感觉 setState() 是异步的,大佬知道的艾特我一下😂 |
7
liuzhaowei55 279 天前 via Android 1
@Jarvis666 应该就是大佬说的 setState 异步更新的问题
https://stackblitz.com/edit/github-cnzc4l-wldcop?file=src%2FApp.tsx 用 useEffect 等 user 改变后再 callback 就成了 |