5

I received an error when trying to SetState using a Promise as a callback in React. This is likely due to an error on my part and would like some clarification on set State in React. The error message I am receiving is as follows.

ERR: "Invalid argument passed as callback. Expected a function. Instead received: [object Promise]"

I have refactored my code example below (edit) to try and provide use to others.

    this.setState({ value: v }, this.callAsync)

// Async function 

  callAsync = async () => {
    await this.props.foo({
    // Something async-y
   })
 .then(success => console.log(success)
 }
o1n3n21
  • 355
  • 1
  • 6
  • 18

1 Answers1

10

Re the code in your original question:

this.setState({ value: v }, this.callAsync())

An async function always returns a promise, which isn't (of course) a callback. In your case, that promise resolves with undefined as you haven't done a return in your callAsync.

If your goal is to call callAsync after the state update is complete, then wrap the call in another function, e.g.:

this.setState({value: v}, async () => {
    try {
        await this.callAsync();
    } catch (e) {
        // handle error
    }
});

or

this.setState({value: v}, () => {
    this.callAsync().catch(e => {
        // handle error
    });
});

Note that it's essential to handle potential errors; otherwise, you'll get unhandled resolution errors if the promise returned by this.props.foo is rejected.


Re the code in your modified question:

This is just a simple case of this not being what you expect in the callback, as described in detail in this question's answers. The solution above also works for that, conveniently; it's one of the solutions listed by the answers there. And it handles errors correctly, which some of the other answers to that question (using this.callAsync.bind(this) for instance) won't.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875