React useReducer hook and functional component lifecycle guarantees

184 views Asked by At

I'd like to confirm an assumption I am making about functional components and useReducer. From my understanding useState is useReducer under the covers so I'll use useState in this example to simplify.

function Example(){
 const [count, setCount] = useState(0);
 
 return <Button onClick={()=> setCount(c=>c+1)} >{count}</button>
}

Do I have a guarantee that after calling setCount the next render cycle will include the updated value for count. I know that updates can be batched such that setCount could be called multiple times before I see a render but is it possible to see a render before the change from setCount is applied?

Batching updates could result in something like this (assuming I call setCount again in the same event invocation or with suspense at play):

0
click => 1
click, click => 3 // 2 did not result in a render
click, click, click => 6 // 4 and 5 did not result in a render

This is why it is critical to use the delegate overload of setCount to ensure it is modifying the current version of the state.

However, is it possible to see the same state rendered twice, once before click and again after:

0
click => 0
1
click => 2

In the example above the count started at 0, I clicked (calling setCount), but then I see an old "queued" render before setCount is "applied". So even though I clicked and called setCount I saw an old render before seeing the new value triggered by setCount. Is this possible or is it safe to assume that I will never see a render with a value that is older than the value in the last setCount call.

0

There are 0 answers