如何在不重新加载页面的情况下将用户重定向到 redux saga 上的另一个页面

How to redirect user to another page on redux saga without reloading the page

你好我正在做一个项目,在这个项目中我使用 Redux saga 异步 action.I 当我发送一个操作来编辑用户详细信息时有问题,如果用户详细信息成功得到更新,我想将用户重定向到另一个页面。这在我的项目中有效,但它正在重新加载页面,我希望它不应该重新加载页面,因为我正在使用 window.location 重定向,我如何在这里使用 react-router 停止重新加载,或者是否有任何其他方法

function* fetchData(){
  try{
    
      yield call(editgetUser)
    yield put(userEditSuccess);
Window.location="/user/home"   
  } catch(e){
    yield yield put(userEditFailure);
Window.location="/user/login"   
  }
}

function* watchFetchData(){
  yield takeEvery(EDIT, fetchData);
}
function* fetchData(){
  try{
    
      yield call(editgetUser)
    yield put(userEditSuccess);
    window.history.pushState({},'',"/user/home")
  } catch(e){
    yield yield put(userEditFailure);
    window.history.pushState({},'',"/user/login")  
  }
}

function* watchFetchData(){
  yield takeEvery(EDIT, fetchData);
}

此文档也很有帮助。 https://developer.mozilla.org/zh-CN/docs/Web/API/History/pushState

我之前也卡在过这种问题,既然要避免页面重载就得用react-router-dom提供的history对象。我们需要历史对象来实现您的目标,但是历史对象在决定是否导航的传奇中不可用,我们必须找到一种方法将历史对象传递给传奇,以便我们可以从传奇。让我们看看我们将如何实现这一目标

方案一(使用react hook组件)

假设您正在使用 React Hook 组件,因此是解决方案..

 // component to dispatch action
 import {useHistory,useDispatch} from 'react-router-dom'
 function MainComponent(){
    const history = useHistory();
    const dispatch = useDispatch();
    return(
         <div>
             <button 
                onPress={()=>
                   dispatch({
                       type:"EDIT",
                       payload:{},
                       history:history // here we pass reference of history object
                  })}>Click ME </button>
         </div>
      )
}




// Your saga function modified
// add action as a param to fetchdata
function* fetchData(action){ // we take the action param
  try{
       yield call(editgetUser)
       yield put(userEditSuccess);
       Window.location="/user/home"  // remove this line
       action.history.push('/user/home') // add this line to your code
   } catch(e){
      yield yield put(userEditFailure);
      Window.location="/user/login"  // remove this line
      action.history.push('/user/login') // add this line to your code
   }
 }

 function* watchFetchData(){
    yield takeEvery(EDIT, fetchData);// fetch data will have an action attatched to it as a param when called
 }

如果您使用的是 class 组件,您可以通过调用 this.props.history 获取历史记录并将引用传递给调度的操作。

为了扩展 Solomon 的回答,在操作中发送 services/non-serializable 对象(例如历史记录)的一个缺点是,从更高级别的角度来看,它会使用与操作本身无关的实现逻辑来膨胀操作接口。

有时,当给定对象与 React 树的特定部分相关时这是不可避免的,但是对于像历史这样的全局服务,您可以在 运行 saga 中间件时将这些东西传递给 sagas。

https://redux-saga.js.org/docs/api#middlewarerunsaga-args

middleware.run(saga, ...args)

这样你就可以将参数传递给 root saga。当涉及到将它传送到 saga 树的其他部分时,有多种方法。我建议使用 setContext/getConext 效果。有关此的更多详细信息,请在此处查看我的其他答案: