React redux-saga中接口返回401时react-router-redux跳转失效如何解决
Redux-saga 401响应跳转失效排查与解决方案
核心失效原因
- 如果你使用的是react-router v4及以上版本,
react-router-redux已经停止维护,不兼容新版本路由,跳转逻辑自然不会生效 - 即使版本匹配,也需要先完成路由状态和redux store的绑定配置,否则
pushaction无法被路由中间件识别执行 - 大概率存在判断逻辑未触发的问题:接口返回的401状态码通常存放在
err.response.status字段,而非err.message,可以先打印err对象确认判断分支是否执行
正确实现方案
这里提供两种可直接落地的方案,优先推荐第二种轻量方案,出错概率更低。
方案1:通过connected-react-router绑定路由状态到Redux
适合需要在redux中统一管理路由状态的场景:
- 安装兼容新版本路由的官方维护依赖
npm install connected-react-router history - 创建全局history实例
// src/history.js import { createBrowserHistory } from 'history' export default createBrowserHistory() - 配置redux绑定路由状态
// src/reducers/index.js import { combineReducers } from 'redux' import { connectRouter } from 'connected-react-router' import history from '../history' const rootReducer = combineReducers({ router: connectRouter(history), // 保留其他业务reducer }) export default rootReducer// src/store.js import { createStore, applyMiddleware } from 'redux' import createSagaMiddleware from 'redux-saga' import { routerMiddleware } from 'connected-react-router' import rootReducer from './reducers' import history from './history' import rootSaga from './sagas' const sagaMiddleware = createSagaMiddleware() const store = createStore( rootReducer, applyMiddleware(routerMiddleware(history), sagaMiddleware) ) sagaMiddleware.run(rootSaga) export { store, history } - 根组件包裹路由容器
// src/App.js import { ConnectedRouter } from 'connected-react-router' import history from './history' function App() { return ( <ConnectedRouter history={history}> {/* 原有路由配置 */} </ConnectedRouter> ) } - 修改saga跳转逻辑
import { call, put } from "redux-saga/effects"; import { push } from 'connected-react-router' import { AUTH_LOGOUT_SUCCESS } from "constants"; export function* errorHandler(err) { if (err.response?.status === 401 || err.message.includes("401")) { yield put({ type: AUTH_LOGOUT_SUCCESS }); yield put(push('/login')); } }
方案2:直接操作全局history跳转(更简单)
不需要额外配置redux路由绑定,直接操作history实例即可实现跳转:
- 和方案1共用同一个全局history实例,无需修改store、reducer配置
- 直接修改saga代码:
import { call, put } from "redux-saga/effects"; import { AUTH_LOGOUT_SUCCESS } from "constants"; import history from '../history' export function* errorHandler(err) { if (err.response?.status === 401 || err.message.includes("401")) { yield put({ type: AUTH_LOGOUT_SUCCESS }); history.push('/login') } }
内容的提问来源于stack exchange,提问作者Loki
相关产品推荐
相关产品推荐

