I’m not sure if it’s just me, but dealing with how React states are updated asynchronously is a nightmare.
Instance variables (useRef with functional components) are updated immediately and are always up to date. It seems like it would be easier to track all of the state in instance variables, and then call setState() to update the UI asynchronously.
This way, there’s a simple consistent model of the data, and the UI render is completely separate and truly represents the “view” only. This also means that setState can always be called without looking at the previous state value; it will always be setStateXYZ(xyzInstance).