react-router-dom v6中如何在Redux Action中使用BrowserHistory
在React Router v6的Redux Action中实现页面导航
首先要明确:React Router v6的BrowserRouter不再支持传入history属性,你原来的写法在v6里不会生效,下面给你三种可行的解决办法:
方案1:用Router组件替代BrowserRouter,配合自定义history对象
这是最接近你原有写法的方案,只需要修改index.js中的路由组件:
// index.js import { Router } from 'react-router-dom'; // 替换BrowserRouter为Router import history from './history'; root.render( <Router history={history}> <Provider store={store}> <App /> </Provider> </Router> )
你的history.js和Redux Action代码不需要改动,history.push('/')可以正常触发页面导航。
方案2:在组件中传递useNavigate函数到Action
这是React Router v6官方推荐的无依赖写法,不需要额外引入history库:
- 在调用Action的组件中,通过
useNavigate获取导航函数,传递给Action:
// 示例组件(比如StreamCreate.js) import { useNavigate } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { createStream } from './actions'; const StreamCreate = () => { const dispatch = useDispatch(); const navigate = useNavigate(); const handleSubmit = (formData) => { // 把navigate函数传给action dispatch(createStream(formData, navigate)); }; // ...表单渲染和其他逻辑 };
- 修改Action,接收并调用
navigate函数:
// Actions export const createStream = (data, navigate) => async (dispatch, getState) => { const { userId } = getState().auth; try { const response = await addStream({ ...data, userId }); dispatch({ type: STREAM_ADDED, payload: { stream: response.data }, }); navigate('/'); // 调用导航函数 } catch (ex) {} };
方案3:通过Redux Middleware统一处理导航
如果你的多个Action都需要导航逻辑,可以创建一个自定义Middleware来集中处理:
- 创建history中间件:
// historyMiddleware.js import { createBrowserHistory } from 'history'; const history = createBrowserHistory(); const historyMiddleware = () => next => action => { // 监听自定义的导航Action if (action.type === 'NAVIGATE_TO') { history.push(action.payload.path); } return next(action); }; export default historyMiddleware;
- 在Redux Store中注册这个Middleware:
// store.js import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import historyMiddleware from './historyMiddleware'; import rootReducer from './reducers'; const store = createStore( rootReducer, applyMiddleware(thunk, historyMiddleware) ); export default store;
- 在Action中触发导航Action:
// Actions export const createStream = (data) => async (dispatch, getState) => { const { userId } = getState().auth; try { const response = await addStream({ ...data, userId }); dispatch({ type: STREAM_ADDED, payload: { stream: response.data }, }); // 触发导航Action dispatch({ type: 'NAVIGATE_TO', payload: { path: '/' } }); } catch (ex) {} };
内容的提问来源于stack exchange,提问作者Nazmul
相关产品推荐
相关产品推荐

