reactJS how to stop it listening to ajax request

六月ゝ 毕业季﹏ 提交于 2019-12-30 07:42:49

问题


I have ajax call in componentdidmount. And and then setState inside the ajax promise.

The code is like this

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?
}

This causes error 'can not setstate on an unmounted component', when I navigate to other route.

So I think what I should do is remove axios listener in the componentwillunmount. How to would you do it?


回答1:


A very simple solution could be to set a flag on unmount and utilize it within the promise resolution, like so:

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;
}



回答2:


I have find a great solution that has been defined by 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;
    },
  };
};

How to use:

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

the solution has been found there.

My implementation.

Inside my function

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) that function returns promise from axios.

when component will unmount cancel function should be invoked.

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

enjoy.



来源:https://stackoverflow.com/questions/37771305/reactjs-how-to-stop-it-listening-to-ajax-request

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!