如何使用反应路由器更改路由时取消ajax

时间:2017-03-02 22:33:17

标签: react-router rxjs rxjs5 react-router-redux redux-observable

 export const getSomethingEpic = action$ =>
  action$
    .ofType(GET_SOMETHING)
    .switchMap(action =>
      ajax('url/api/something')
        .map((json) => {
          return getSomethingEndAct(json.response);
        })
        .takeUntil(action$.ofType('@@router/LOCATION_CHANGE'))
    );

情况如下:

页面A有一个反应路由器链接到页面B,在页面B上componentDidMount我调度getSomething动作。 Ajax可以完美取消。但是,如果页面B已加载且ajax已完成,我们将从页面B路由到页面C,然后使用浏览器返回按钮再次路由到页面B,将再次在componentDidMount中调度操作getSomething,但这次取消了ajax

我不明白为什么ajax被取消,因为位置更改是在getSomething操作之前。 或者在路线改变时如何取消ajax?

我尝试构建一个示例,但我无法使用react-router-redux来同步浏览器历史记录。这是http://jsbin.com/dewixurece/edit?js,console,output 如果使用hashHistory它会工作,但会有两个位置更改操作,应该是一个而不是我不知道原因。

它是一个很棒的lib,我真的很喜欢RX编程的想法,但仍然在学习,希望我们可以有更多的例子。谢谢,如果有人可以提供帮助。

1 个答案:

答案 0 :(得分:1)

(基于我们在评论中的讨论)

如果您想在输入路线时启动请求,但是如果您在完成路线之前离开该路线则取消请求,您将在componentWillUnmount中发送开始操作,并在const getSomethingEpic = action$ => action$.ofType('GET_SOMETHING') .switchMap(action => ajax('url/api/something') .map((json) => { return getSomethingEndAct(json.response); }) .takeUntil(action$.ofType('GET_SOMETHING_CANCELLED')) ); class B extends Component { componentDidMount() { store.dispatch({ type: 'GET_SOMETHING' }); } componentWillUnmount() { store.dispatch({ type: 'GET_SOMETHING_CANCELLED' }); } render() { return ( <h1>B route</h1> ); } } 中发送取消操作{1}}

store.dispatch

演示:http://jsbin.com/zomire/edit?js,output

为简单起见,我直接使用了connect()。如果您愿意,可以在真实应用中使用动作创建者和/或onCreate

即使ajax请求已经完成,调度取消操作通常也不是问题 - 但如果确实存在问题,或者您希望仅在真正需要的情况下发送它,则您需要执行此操作。我需要存储某种状态,您可以使用它来了解请求是否仍处于待处理状态。您可以将此状态存储为本地组件状态或存储在redux存储中。