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 theTestComponent
with 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.