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编程的想法,但仍然在学习,希望我们可以有更多的例子。谢谢,如果有人可以提供帮助。
答案 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存储中。