如何在不重新加载页面的情况下将用户重定向到 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 上的另一个页面的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用任何浏览器相关组件的情况下将数据发布到另一个网站?
如何在不重新加载页面的情况下将任意 JSON 发送到 node.js?
路由更改时如何在不滚动 Reactjs 的情况下将页面置于顶部