5

Does anybody know if in React it's possible to use an async updater parameter in setState(updater) ? I have the following code which is not working (f is called but the UI is not updated):

this.setState( async (prevState) => ({
   foo: await f(prevState.someData)
}))      

Apparently the async parameter is a problem. I had to use this ugly alternate version:

this.setState( async (prevState) => {
   this.setState({
      foo: await f(prevState.someData)
   })      
})

Is there a better way to write the above code?

Mμ.
  • 8,382
  • 3
  • 26
  • 36
nino.porcino
  • 1,133
  • 1
  • 8
  • 16

3 Answers3

1

Then you can setState twice.

this.setState((prevState) => {
    f(prevState.someData);        

    // Don't change state now.
    return {}; 
})

async f(someData) {
  this.setState(prevState) {
    // Do something
  }
} 
Trantor Liu
  • 8,770
  • 8
  • 44
  • 64
0

I am assuming that you are calling setState on a method. So why not put async on the method?

async handleSomething () {
  //.. some logic

  this.setState(prevState => ({
    foo: await f(prevState.someData)
  }))
}
Mμ.
  • 8,382
  • 3
  • 26
  • 36
  • 1
    D-reaper is right - `setState()` should be pretty much an atomic operation and is a bad place for async ops. Put async fetches in a method call. – Omortis Jun 27 '17 at 13:34
  • this is not allowed since `await` is inside a lambda function, and that needs to be `async` as well (the typescript compiler gives me an error). – nino.porcino Jun 27 '17 at 13:35
  • 1
    @Omortis: I would usually move fetches out of the `setState`, the problem here is that I have a previous `setState` call, so I can't refer to `this.state` for my fetch; I am forced to use `setState(func)` in order to have access to the state. – nino.porcino Jun 27 '17 at 13:42
-1

You cannot use async inside of setState since setState needs to be a pure function with no side effects. Just do the async method before the setState call:

async classMethod = () => {
    let response = await someAsyncOperation(this.state.someData);
    this.setState({ someData: response });
}
whs.bsmith
  • 386
  • 1
  • 2
  • 12
  • 1
    I can't use `this.state.someData` because in my `classMethod` I have a previous `setState` call which makes `this.state` unreliable. – nino.porcino Jun 27 '17 at 14:21