【问题标题】:How to redirect user to another page on redux saga without reloading the page如何在不重新加载页面的情况下将用户重定向到 redux saga 上的另一个页面
【发布时间】: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);
}

【问题讨论】:

    标签: reactjs redux react-router redux-saga


    【解决方案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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-22
          • 1970-01-01
          • 1970-01-01
          • 2020-04-20
          • 2011-10-31
          相关资源
          最近更新 更多