You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级React Router v6后,如何在Redux Saga中使用useNavigate导航?

解决Redux Saga中React Router v6导航问题的方案

因为你已经移除了connected-react-router,又不想每次派发Action都传useNavigate,下面几个实用方案可以适配你现有代码的情况:

方案1:将navigate实例存入Redux Store

在根组件中获取useNavigate实例并存入Redux,之后在Saga里通过select取出使用:

  1. 创建管理导航的slice:
// features/navigate/navigateSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { NavigateFunction } from 'react-router-dom';

interface NavigateState {
  navigate: NavigateFunction | null;
}

const initialState: NavigateState = {
  navigate: null,
};

export const navigateSlice = createSlice({
  name: 'navigate',
  initialState,
  reducers: {
    setNavigate: (state, action: PayloadAction<NavigateFunction>) => {
      state.navigate = action.payload;
    },
  },
});

export const { setNavigate } = navigateSlice.actions;
export const selectNavigate = (state: RootState) => state.navigate.navigate;
  1. 在根组件注入navigate实例:
// App.tsx
import { useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { setNavigate } from './features/navigate/navigateSlice';
import { useEffect } from 'react';

function App() {
  const navigate = useNavigate();
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(setNavigate(navigate));
  }, [navigate, dispatch]);

  return (
    {/* 你的应用内容 */}
  );
}
  1. 在Saga中取出使用:
function* watchStatus(
    action: ActionType<typeof startActions.changeStatus>
): SagaIterator {
    if (action.payload.status === "END_CREATE") {
        const data: ReturnType<typeof getDataRequest> = yield select(
            getDataRequest
        );
    } else if (action.payload.status === "END_VIEW") {
        const navigate = yield select(selectNavigate);
        navigate('/target-path');
    }
}

方案2:全局导航服务(单例模式)

创建独立的导航服务文件,用单例存储navigate实例,Saga中直接导入调用:

  1. 编写导航服务:
// services/navigateService.ts
import { NavigateFunction } from 'react-router-dom';

let navigateInstance: NavigateFunction | null = null;

export const navigateService = {
  setNavigate: (navigate: NavigateFunction) => {
    navigateInstance = navigate;
  },
  navigate: (to: string) => {
    navigateInstance?.(to);
  },
};
  1. 在根组件初始化服务:
// App.tsx
import { useNavigate } from 'react-router-dom';
import { navigateService } from './services/navigateService';
import { useEffect } from 'react';

function App() {
  const navigate = useNavigate();

  useEffect(() => {
    navigateService.setNavigate(navigate);
  }, [navigate]);

  return (
    {/* 你的应用内容 */}
  );
}
  1. 在Saga中直接调用:
import { navigateService } from '../services/navigateService';

function* watchStatus(
    action: ActionType<typeof startActions.changeStatus>
): SagaIterator {
    if (action.payload.status === "END_CREATE") {
        const data: ReturnType<typeof getDataRequest> = yield select(
            getDataRequest
        );
    } else if (action.payload.status === "END_VIEW") {
        navigateService.navigate('/target-path');
    }
}

方案3:Action触发+组件监听导航

让Saga派发导航Action,在组件中监听并执行导航,更符合Redux单向数据流:

  1. 定义导航Action和slice:
// features/navigate/navigateSlice.ts
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

interface NavigateState {
  targetPath: string | null;
}

const initialState: NavigateState = {
  targetPath: null,
};

export const navigateSlice = createSlice({
  name: 'navigate',
  initialState,
  reducers: {
    navigateTo: (state, action: PayloadAction<string>) => {
      state.targetPath = action.payload;
    },
    resetTargetPath: (state) => {
      state.targetPath = null;
    },
  },
});

export const { navigateTo, resetTargetPath } = navigateSlice.actions;
export const selectTargetPath = (state: RootState) => state.navigate.targetPath;
  1. 在Saga中派发导航Action:
import { navigateTo } from '../features/navigate/navigateSlice';

function* watchStatus(
    action: ActionType<typeof startActions.changeStatus>
): SagaIterator {
    if (action.payload.status === "END_CREATE") {
        const data: ReturnType<typeof getDataRequest> = yield select(
            getDataRequest
        );
    } else if (action.payload.status === "END_VIEW") {
        yield put(navigateTo('/target-path'));
    }
}
  1. 在根组件监听并执行导航:
// App.tsx
import { useNavigate } from 'react-router-dom';
import { useSelector, useDispatch } from 'react-redux';
import { selectTargetPath, resetTargetPath } from './features/navigate/navigateSlice';
import { useEffect } from 'react';

function App() {
  const navigate = useNavigate();
  const targetPath = useSelector(selectTargetPath);
  const dispatch = useDispatch();

  useEffect(() => {
    if (targetPath) {
      navigate(targetPath);
      dispatch(resetTargetPath());
    }
  }, [targetPath, navigate, dispatch]);

  return (
    {/* 你的应用内容 */}
  );
}

内容的提问来源于stack exchange,提问作者pitchdiesel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:35:40