I created a reducer that increments a global UID on every dispatch with the action increment. The initial value of the UID is 0.
Expectation:
I expected that the UID is incremented by 1 on every dispatch.
Reality:
The UID increments by 2 and the logged state are inconsistent with the real state's value.
My component:
import React, { useReducer } from "react"
let uid = 0
function nextUID() {
uid = uid + 1
return uid
}
function reducer(state, action) {
switch (action.type) {
case "increment":
const uid = nextUID()
const newState = `current UID is ${uid}!`
console.log(newState)
return newState
default:
return state
}
}
function TestComponent() {
const [state, dispatch] = useReducer(reducer, "not clicked yet")
return <button onClick={() => dispatch({ type: "increment" })}>{state}</button>
}
export default TestComponent
Output:
| Num. Clicks | Button Label | Console Output |
|---|---|---|
| 0 | not yet clicked | |
| 1 | current UID is 1! | current UID is 1! |
| 2 | current UID is 3! | current UID is 2! |
| 3 | current UID is 5! | current UID is 4! |
Question:
How is it possible, that the button label is current UID is 3! while the console output for the state change was current UID is 2!? Is it possible that react calls the reducer multiple times and discards the console output the second time?
Additional Information:
- I also tried to use
const uidRef = useRef(0)in theTestComponentwith an anonymous reducer that incrementsuidRef.current. The behavior was the same. - I also tried adding a console output to
nextUID(). The output wasnew uid 1; new uid 2; new uid 4; ...
Thanks.