score:0

You should be able to use this._isMounted to check if the component is actually mounted.

handleSubmit() {
  this.setState({loading: true})
  someAsyncFunc()
    .then(() => {
      return this.props.onSuccess()
    })
    .finally(() => {
      if (this && this._isMounted) { // check if component is still mounted
        this.setState({loading: false})
      }
    })
}

But be aware that this approach is considered to be an anitpattern. https://reactjs.org/blog/2015/12/16/ismounted-antipattern.html

score:0

What about

componentWillUnmount() {  
    // Assign this.setState to empty function to avoid console warning
    // when this.setState is called on an unmounted component
    this.setState = () => undefined;
}

score:1

Unfortunately you have to keep track of "isMounted" yourself. To simplify you control flow you could use async/await:

handleSubmit() {
  this.setState({loading: true})
  try {
    await someAsyncFunction()
    await this.props.onSuccess()
  } finally {
    if (this._isMounted) {
      this.setState({loading: false})
    }
  }
}

This is actually mentioned in the react docs, which points to this solution: https://gist.github.com/bvaughn/982ab689a41097237f6e9860db7ca8d6

If your someAsyncFunction supports cancelation, you should do so in componentWillUnmount, as encouraged by this article. But then - of course - check the return value and eventually not call this.props.onSuccess.

score:1

class myClass extends Component {
  _isMounted = false;

  constructor(props) {
    super(props);

    this.state = {
      data: [],
    };
  }

  componentDidMount() {
    this._isMounted = true;
    this._getData();
  }

  componentWillUnmount() {
    this._isMounted = false;
  }

  _getData() {
    axios.get('example.com').then(data => {
      if (this._isMounted) {
        this.setState({ data })
      }
    });
  }


  render() {
    ...
  }
}

Related Query

More Query from same tag