如何避免Okta令牌刷新后Redux Store与页面重复刷新
问题解决方案:Okta令牌刷新导致Redux Store重置
问题根源
你的代码中,AppWithRouterAccess组件每次因authState.isAuthenticated更新而重渲染时,都会重新执行createStore创建新的Redux Store实例,这直接导致之前的应用状态被清空。
核心修复方案
保证Redux Store只初始化一次,而非组件每次重渲染都重建。
修改后的代码
import React from "react"; import { Route, Redirect, Switch } from "react-router-dom"; import { useOktaAuth } from "@okta/okta-react"; import { Superadmin } from "../../../../Application_Constants"; import { AuthPage } from "./AuthPage"; import { ErrorPage1 } from "../../errors/ErrorPage1"; import { makeStyles, useTheme } from "@material-ui/core/"; import { Provider } from "react-redux"; import { createStore, applyMiddleware } from "redux"; import thunk from "redux-thunk"; import reducer from "../../redux/reducer"; import Header from "../../header/Header"; // 将Store创建移到组件外部,模块加载时仅初始化一次 const store = createStore(reducer, applyMiddleware(thunk)); const AppWithRouterAccess = () => { const theme = useTheme(); const { authState, oktaAuth } = useOktaAuth(); return ( <Switch> {/* 统一处理/auth路由的认证逻辑 */} <Route path="/auth"> {authState.isAuthenticated ? <Redirect to="/" /> : <AuthPage />} </Route> <Route path="/error" component={ErrorPage1} /> {/* 已认证用户的路由区域 */} {!authState.isAuthenticated ? ( <Redirect to="/auth/login" /> ) : ( <Provider store={store}> <Header /> {/* 在此添加其他需要认证的页面路由 */} </Provider> )} </Switch> ); }; export default AppWithRouterAccess;
额外优化建议
- 拆分已认证布局组件:把包含Provider的部分拆成独立组件,避免因authState变化触发Provider的重渲染:
// 单独创建已认证布局组件 const AuthenticatedLayout = () => { return ( <Provider store={store}> <Header /> {/* 放置所有已认证页面的路由 */} </Provider> ); }; // 在主组件中使用 {!authState.isAuthenticated ? ( <Redirect to="/auth/login" /> ) : ( <AuthenticatedLayout /> )}
- 动态初始化Store的场景:如果需要根据特定参数动态初始化Store(比如用户角色),可以用
useMemo缓存Store实例,确保仅在必要时重建:
const store = useMemo(() => { // 这里可以添加动态初始化逻辑,比如传入初始state return createStore(reducer, applyMiddleware(thunk)); }, []); // 空依赖数组保证仅初始化一次
总结
核心问题是Store的重复创建,只要保证Store实例唯一,就能解决authState更新导致的状态重置问题。
内容的提问来源于stack exchange,提问作者akshada
相关产品推荐
相关产品推荐

