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

Posted

技术标签:

【中文标题】如何在不重新加载页面的情况下将用户重定向到 redux saga 上的另一个页面【英文标题】:How to redirect user to another page on redux saga without reloading the page 【发布时间】:2021-12-27 07:37:01 【问题描述】:

嗨,我正在做一个项目,在这个项目中,我使用 Redux saga 进行异步操作。当我发送操作以编辑用户详细信息时,我有一个问题,如果用户详细信息成功更新,我想将用户重定向到另一个页面。这在我的项目中有效,但它正在重新加载页面,我希望它不应该重新加载页面,因为我正在使用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);

【问题讨论】:

【参考方案1】:

我之前一直被这种问题困扰,因为你想避免页面重新加载,这意味着我们必须使用 react-router-dom 提供的历史对象。我们需要历史对象来实现您的目标,但是历史对象在决定是否导航的 saga 上不可用,我们必须找到一种方法将历史对象传递给 saga,以便我们可以从传奇。让我们看看我们将如何实现这一目标

方案一(使用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
 

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

【讨论】:

【参考方案2】:
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

【讨论】:

【参考方案3】:

为了扩展 Solomon 的回答,在动作中发送服务/不可序列化对象(例如历史记录)的一个缺点是,它会使动作接口膨胀,其实现逻辑从更高级别的角度来看与动作本身无关。

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

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

middleware.run(saga, ...args)

通过这种方式,您可以将参数传递给根 saga。当谈到将它放到 saga 树的其他部分时,有多种方法。我建议使用setContext/getConext 效果。有关这方面的更多深入信息,请参见我的其他答案: How to pass args from sagaMiddleware to action watcher

【讨论】:

以上是关于如何在不重新加载页面的情况下将用户重定向到 redux saga 上的另一个页面的主要内容,如果未能解决你的问题,请参考以下文章

如何在不重新加载 HTML 页面的情况下重定向锚标记链接?

如何在不使用任何浏览器相关组件的情况下将数据发布到另一个网站?

如何在不重新加载页面的情况下将任意 JSON 发送到 node.js?

路由更改时如何在不滚动 Reactjs 的情况下将页面置于顶部

在不使用经典 RPyC 的情况下将 RPyC 的标准输出重定向到本地客户端

在不使用 jQuery 重新加载页面的情况下将 Flask 输入更新为 HTML [重复]