Open Izhaki opened 5 years ago
I know this is half a year old, but I found the discussion interesting. I'm by no means a hooks expert, but I have a thought I'd like to share.
With regards to your proposed docs addition:
useMemo(x, []) and useCallback(cb, []) are the identical to useRef(x).current and useRef(cb).current respectively.
I still think there's quite a big difference between useMemo(x, [])
and useRef(x).current
as useMemo
expects a create function where useRef
expects a value.
As such, the equivalence you see would actually be that useMemo(()=>x, [])
is equivalent to useRef(x).current
.
But even then, useMemo
gives you the benefit of an expensive create function being called only once. If you want to use useRef
with a create function, you're forced to call this function on every render, that is via useRef(expensive())
, which could perform very poorly.
Additionally, note also this part of the docs:
You may rely on useMemo as a performance optimization, not as a semantic guarantee. In the future, React may choose to “forget” some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without useMemo — and then add it to optimize performance.
The Proposal
As part of a deductive exercise, in this issue I essentially proposed changing:
To:
With
useRef
:Object.is
).These optimisations are terribly minute, but understanding React is what at stake here.
The Question
Then the reply came:
The Docs
I couldn't think of one, so posted an SO question, for which a reply came with reference to these docs:
In the codesandbox example provided, we see
useCallback
with empty dependencies:Yet changing the
useCallback
above touseRef(cb).current
works all the same:Misguidance?
Now I understand the docs focus on a callback ref, so using
useCallback
makes sense.But this statement is misleading:
First, it promotes the (in my view somewhat popular) misconception that
useRef
is solely there to refer to DOM elements (filled via object ref).Further, this statement confounds
useRef
with object ref:useRef
is another.What
useRef
is Really forFar from this,
useRef
raison d'être is the ability to create stable values; callbacks are no exception:Storing DOM elements is a popular, yet a specific use case for refs.
Another Example
From the docs:
I argue that this statement distorts people's understanding of core React concept. It builds a mental model where there is such 'cosmic' mapping:
useRef
→ object refuseCallback
→ callback refThis is incorrect.
(Nitpickers, like me, will point out at this point that both "object ref" and "callback ref" have "ref" in them!)
What needs changing?
First,
useRef
should not be part of this sentence:Instead:
Also this:
To this:
Then, if
useRef(cb).current
is identical to (and slightly more efficient than)useCallback(cb, [])
, perhaps this is something worth mentioning?More generally, if correct, I would expect to see this somewhere in the docs:
Learning this is conceptually important, thus so is teaching.