1

this is NOT the problem cause by StrictMode.
here is my code first, a Counter:

let outsideCount = 0
function Counter() {
  const [count, setCount] = useReducer(doCounting, 0)

  function doCounting(count) {
    console.log(`count: ${count}`)
    console.log(`outsideCount: ${outsideCount}`)
    console.log('---------divider---------')

    outsideCount++
    return count + 1
  }

  return (
    <div>
      <span>count: {count}</span>
      <button onClick={setCount}>Click Me!</button>
    </div>
  )
}

and the output: click 1 time:

count: 0
outsideCount: 0
---------divider---------
count: 0
outsideCount: 1
---------divider---------  // <<<<<<< That's the point I confused. why it triggered twice?

click 2 time:

count: 1
outsideCount: 3            // <<<<<<< I KNEW that cause by StrictMode
---------divider---------  // this time it only trigger once.
// ^^^^^^^^^ but why it trigger twice only at the first click?

click 3 time:

click 3 time:
count: 2
outsideCount: 5            // <<<<<<< I KNEW that cause by StrictMode
---------divider---------
// ^^^^^^^^^ the third time trigger once like expected. the first-click confused me.

I've already knew that StrictMode will make outsideCount added twice every click due to test some side-effect that might not be notice by programmer.
and after build as production, the outsideCount added once as expected.

but why the first click will trigger function doCounting twice? the console shows 2 divider when the first time I click.
also, after build as production, the doCounting still trigger twice when the first time I clicked.

Not looking for other solutions or good/bad practice stuff, just wanna know why

FlyC
  • 1,844
  • 1
  • 15
  • 18

1 Answers1

0

though the behavior or codes' running sequence is not clearly understood yet,
but I think I got some clue about it: function-memory-address

the function doCounting is triggered and do something at the first time by the click:
---> the console printed, the value is returned,
then the component re-rendered, so the doCounting function is re-created again.
then, somehow, the re-created function is triggered, again

I guess the second time is the right way what React truly wanna do. I guess.

the easiest way to avoid the changing of function-memory-address is like the same way we avoid Object-memory-address changed: useMemo or useCallback or declare-it-outside

// useMemo
const doCounting = useMemo(() => value => {
  console.log(value)
  console.log('---divider---')
  return value + 1
}, [])

//or

// useCallback
const doCounting = useCallback(value => {
  console.log(value)
  console.log('---divider---')
  return value + 1
}, [])

even though I still don't know when the function is triggered, but at least we know that is the memory-address problem.

hope someone to supplement the right codes' running sequence. thx

FlyC
  • 1,844
  • 1
  • 15
  • 18