reactJS如何阻止它监听ajax请求

IT技术 reactjs axios
2021-04-27 15:04:13

我在 componentdidmount 中有 ajax 调用。然后在 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?
}

当我导航到其他路由时,这会导致错误“无法在未安装的组件上设置状态”。

所以我认为我应该做的是删除componentwillunmount中的axios监听器。你会怎么做?

2个回答

一个非常简单的解决方案可能是在卸载时设置一个标志并在Promise解析中使用它,如下所示:

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();

已在那里找到解决方案

我的实现。

在我的函数里面

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) 该函数从 axios 返回 promise。

当组件卸载时应调用取消函数。

componentWillUnmount() {
        this.promiseShareByEmail.cancel();
    }

请享用。