在使用React路由器更改路线时,如何取消AJAX


 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页A在B Page B componentdidmount上有一个React路由器链接i Dispatch getomething操作。Ajax可以完美取消。但是,如果Page B已加载并且AJAX完成,我们将从页面B到C页C,然后使用浏览器返回按钮再次路由到B Page B,compotemthing将再次在ComponentDidMount中派遣,但是这次Ajax被取消了。

我不明白为什么AJAX被取消,因为位置更改是在操作措施之前的位置更改。否则我该怎么做才能取消路线时取消AJAX?

我试图构建一个示例,但是我无法获得React-Router-Redux来同步浏览器历史记录。这是http://jsbin.com/dewixurece/edit?js,console和output如果使用Hashhistory,它将有效,但是将有两个位置更改操作,这应该是一个,我不知道为什么。

这是一个很棒的自由,我真的很喜欢RX编程的想法,但仍在学习并希望我们可以有更多的例子。谢谢任何人可以提供帮助。

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

如果您想在进入路线时启动请求,但是如果您在完成该路线之前离开该路由,请在componentDidMount中派遣起始操作,并在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>
    );
  }
}

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

为简单起见,我直接使用了store.dispatch。如果您喜欢的话,请在您的真实应用中使用动作创建者和/或connect()

派遣取消措施,即使已经完成了AJAX请求,通常也不是问题 - 但是如果它确实需要,则只需派遣它,您就需要存储某种状态您可以使用该请求是否仍在待处理中。您可以将此状态存储为本地组件状态或Redux商店。