reactJS 如何阻止它监听 ajax 请求
reactJS how to stop it listening to ajax request
我有 ajax 调用 componentdidmount。然后在 ajax promise 中设置状态。
代码是这样的
componentDidMount(){
axios.post('mydomian.com/item/',this.state)
.then(function (response) {
const res = response.data
if (res.status === 'OK') {
this.setState({items :res.list})
}else{
console.log('can not load data', response)
}
}.bind(this))
}
componentWillUnmount(){
how to stop everything about axios?
}
当我导航到其他路线时,这会导致错误 'can not setstate on an unmounted component'。
所以我认为我应该做的是删除componentwillunmount中的axios listener。你会怎么做?
一个非常简单的解决方案是在卸载时设置一个标志并在承诺解决方案中使用它,如下所示:
componentDidMount(){
axios.post('mydomian.com/item/',this.state)
.then(function (response) {
if (this.unmounted) return;
const res = response.data
if (res.status === 'OK') {
this.setState({items :res.list})
}else{
console.log('can not load data', response)
}
}.bind(this))
}
componentWillUnmount(){
this.unmounted = true;
}
我找到了 istarkov 定义的一个很好的解决方案
const makeCancelable = (promise) => {
let hasCanceled_ = false;
const wrappedPromise = new Promise((resolve, reject) => {
promise.then((val) =>
hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
);
promise.catch((error) =>
hasCanceled_ ? reject({isCanceled: true}) : reject(error)
);
});
return {
promise: wrappedPromise,
cancel() {
hasCanceled_ = true;
},
};
};
使用方法:
const somePromise = new Promise(r => setTimeout(r, 1000));
const cancelable = makeCancelable(somePromise);
cancelable
.promise
.then(() => console.log('resolved'))
.catch(({isCanceled, ...error}) => console.log('isCanceled', isCanceled));
// Cancel promise
cancelable.cancel();
已找到解决方案 there。
我的实现。
在我的函数中
const promiseShareByEmail = makeCancelable(this.props.requestShareByEmail(obj.email, obj.url));
promiseShareByEmail.promise.then(response => {
const res = response.data;
if (res.code != 0)
throw new Error(res.message);
this.setState({
message: {
text: TextMeasurements.en.common.success_share_test,
code: Constants.ALERT_CODE_SUCCESS
}
});
}).catch(err => {
if (err.isCanceled)
return;
this.setState({
message: {
text: err.message,
code: Constants.ALERT_CODE_ERROR
}
})
});
this.promiseShareByEmail = promiseShareByEmail;
this.props.requestShareByEmail(obj.email, obj.url)
函数 returns 来自 axios 的承诺。
当组件卸载时应调用取消函数。
componentWillUnmount() {
this.promiseShareByEmail.cancel();
}
尽情享受吧。
我有 ajax 调用 componentdidmount。然后在 ajax promise 中设置状态。
代码是这样的
componentDidMount(){
axios.post('mydomian.com/item/',this.state)
.then(function (response) {
const res = response.data
if (res.status === 'OK') {
this.setState({items :res.list})
}else{
console.log('can not load data', response)
}
}.bind(this))
}
componentWillUnmount(){
how to stop everything about axios?
}
当我导航到其他路线时,这会导致错误 'can not setstate on an unmounted component'。
所以我认为我应该做的是删除componentwillunmount中的axios listener。你会怎么做?
一个非常简单的解决方案是在卸载时设置一个标志并在承诺解决方案中使用它,如下所示:
componentDidMount(){
axios.post('mydomian.com/item/',this.state)
.then(function (response) {
if (this.unmounted) return;
const res = response.data
if (res.status === 'OK') {
this.setState({items :res.list})
}else{
console.log('can not load data', response)
}
}.bind(this))
}
componentWillUnmount(){
this.unmounted = true;
}
我找到了 istarkov 定义的一个很好的解决方案
const makeCancelable = (promise) => {
let hasCanceled_ = false;
const wrappedPromise = new Promise((resolve, reject) => {
promise.then((val) =>
hasCanceled_ ? reject({isCanceled: true}) : resolve(val)
);
promise.catch((error) =>
hasCanceled_ ? reject({isCanceled: true}) : reject(error)
);
});
return {
promise: wrappedPromise,
cancel() {
hasCanceled_ = true;
},
};
};
使用方法:
const somePromise = new Promise(r => setTimeout(r, 1000));
const cancelable = makeCancelable(somePromise);
cancelable
.promise
.then(() => console.log('resolved'))
.catch(({isCanceled, ...error}) => console.log('isCanceled', isCanceled));
// Cancel promise
cancelable.cancel();
已找到解决方案 there。
我的实现。
在我的函数中
const promiseShareByEmail = makeCancelable(this.props.requestShareByEmail(obj.email, obj.url));
promiseShareByEmail.promise.then(response => {
const res = response.data;
if (res.code != 0)
throw new Error(res.message);
this.setState({
message: {
text: TextMeasurements.en.common.success_share_test,
code: Constants.ALERT_CODE_SUCCESS
}
});
}).catch(err => {
if (err.isCanceled)
return;
this.setState({
message: {
text: err.message,
code: Constants.ALERT_CODE_ERROR
}
})
});
this.promiseShareByEmail = promiseShareByEmail;
this.props.requestShareByEmail(obj.email, obj.url)
函数 returns 来自 axios 的承诺。
当组件卸载时应调用取消函数。
componentWillUnmount() {
this.promiseShareByEmail.cancel();
}
尽情享受吧。