Closed SukkaW closed 1 year ago
The behavior is correct. The mistake was in your code (if (!singletonRef)
)
The optimization is intentional as useRef has too much overhead because of its hook implementation despite being the simplest hook
The behavior is correct. The mistake was in your code (
if (!singletonRef)
)
That was a typo. I have updated the input
and output
sections. And yet the behavior is still incorrect.
The reference to the singletonRef
is lost during the assignment, thus _v2
is not singletonRef
when _v2
is coming from the cache (_c[1]
). In this case, assigning _v2.current
won't update singletonRef.current
.
Simply put, Object.is(_v2, singletonRef) === false
when _v2
is from _c[1]
and _v
is from _c[0]
;
Pardon me as I still don't see where the mistake is. Could you point out the exact line where it loses the reference? because _v2
is always _v
from the initial commit up until the component unmounts.
Even if useRef is not optimized the only code that would change is _v
Pardon me as I still don't see where the mistake is. Could you point out the exact line where it loses the reference? because
_v2
is always_v
from the initial commit up until the component unmounts.Even if useRef is not optimized the only code that would change is
_v
Anyway, I have put up a re-production at codesandbox: https://codesandbox.io/s/xenodochial-goldberg-lc5iwd?file=/src/App.tsx
And as you can see, the ref value is undefined
during useEffect
which is not supposed to happen.
Okay thank you for making a repro, I'll take a look
I think I understand the issue now. It's not about the useRef
optimization, it's more of knowing that the cache item is fresh. For example, if we have $$equals(c[0], item)
and item
is undefined
, and we have console.log(item)
, the log will never run on initial render because it thinks that c[0]
already exists and the cache never changed (c[0] === undefined
).
The solution here is to change the runtime comparison so that it checks whether or not there's a registered cache.
Input
This is a very common singleton
useRef
pattern: https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contentsOutput
Now
singletonRef.current
will always be undefined.I propose forgetti just to skip
useRef
optimization.useRef
is just like a global variable live within a component's lifecycle, and it is not designed to be read or written during render.