Hooks API - Avoid State Overwrite When Setting State After Await Statement

- 1 answer

Let's say we have a tile grid with the follow behavior:

  • There's a button for adding a tile. The tile will decide if it should be a red or blue tile after some time thinking (1-3secs). The tile will be green while it's thinking what color it should be.
  • Clicking a title will remove the tile from the grid

Let tiles be an array of tile colors which will serve as the state of the tile grid and setTiles as the setter of that state. Given the grid behavior, setTiles should be called during these events:

  • on click of a tile. The clicked tile should be removed from tiles.
  • on click of the add button. A green tile must be added to tiles.
  • after a tile decides what it's color is. The corresponding green value in tiles must be changed to red or green.

I've prepared a codepen of a simple implementation of the grid detailed above. The issue with this is that calls to setTiles after an await statement overwrites state changes that happened between the start and end of the asynchronous statement. I think this is because the function only has reference to the state value before starting the async operation.

What's the best architecture (component changes, callback passing, tile data structure), using SFCs and the Hooks API, to avoid the unintended overwrites and, ultimately, the tile grid having an updated array of tile data at all times?



Solved it by using useReducer. Wasn't aware that with useReducer, you have a "synchronised" state for all dispatched actions. The state overwrite wasn't an issue with the seemingly-central state with reducers. Working code here.