使用反应路由器更改路线时如何取消ajax
How to cancel ajax when route changing using react router
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 的反应路由器 Link,在页面 B 的 componentDidMount 上,我调度了 getSomething 操作。 Ajax可以完美取消。然而,如果页面 B 加载并且 ajax 完成,我们从页面 B 路由到页面 C,然后使用浏览器后退按钮再次路由到页面 B,动作 getSomething 将再次在 componentDidMount 中调度,但是这次ajax 被取消。
我不明白为什么要取消 ajax,因为位置更改先于 getSomething 操作。
或者当路线改变时我应该如何取消ajax?
我尝试构建一个示例,但无法让 react-router-redux 同步浏览器历史记录。这里是 http://jsbin.com/dewixurece/edit?js,console,output
如果使用 hashHistory 会起作用,但是会有两个位置更改操作,应该是一个,我不知道为什么。
这是一个很棒的库,我真的很喜欢 RX 编程思想,但仍在学习中,希望我们能有更多的例子。谢谢,如果有人能帮忙。
(基于我们在评论中的讨论)
如果你想在进入一条路线时开始一个请求,但如果你在路线完成之前离开那条路线就取消它,你可以在 componentDidMount
中调度开始操作,在 [=12= 中调度取消操作=]
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
。如果您愿意,可以在您的真实应用中使用动作创建器 and/or connect()
。
调度取消操作,即使 ajax 请求已经完成通常也不是问题——但如果是或者您希望仅在真正需要时调度它,您将需要存储某种状态,您可以使用它来了解请求是否仍未决。您可以将此状态存储为本地组件状态或在 redux 存储中。
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 的反应路由器 Link,在页面 B 的 componentDidMount 上,我调度了 getSomething 操作。 Ajax可以完美取消。然而,如果页面 B 加载并且 ajax 完成,我们从页面 B 路由到页面 C,然后使用浏览器后退按钮再次路由到页面 B,动作 getSomething 将再次在 componentDidMount 中调度,但是这次ajax 被取消。
我不明白为什么要取消 ajax,因为位置更改先于 getSomething 操作。 或者当路线改变时我应该如何取消ajax?
我尝试构建一个示例,但无法让 react-router-redux 同步浏览器历史记录。这里是 http://jsbin.com/dewixurece/edit?js,console,output 如果使用 hashHistory 会起作用,但是会有两个位置更改操作,应该是一个,我不知道为什么。
这是一个很棒的库,我真的很喜欢 RX 编程思想,但仍在学习中,希望我们能有更多的例子。谢谢,如果有人能帮忙。
(基于我们在评论中的讨论)
如果你想在进入一条路线时开始一个请求,但如果你在路线完成之前离开那条路线就取消它,你可以在 componentDidMount
中调度开始操作,在 [=12= 中调度取消操作=]
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
。如果您愿意,可以在您的真实应用中使用动作创建器 and/or connect()
。
调度取消操作,即使 ajax 请求已经完成通常也不是问题——但如果是或者您希望仅在真正需要时调度它,您将需要存储某种状态,您可以使用它来了解请求是否仍未决。您可以将此状态存储为本地组件状态或在 redux 存储中。