Sunday, May 12, 2024
 Popular · Latest · Hot · Upcoming
29
rated 0 times [  30] [ 1]  / answers: 1 / hits: 6879  / 4 Years ago, wed, may 20, 2020, 12:00:00

using react's ref today can be a little confusing.
back to the days of class components, it was very clear in the docs.



we should use refs mostly for DOM elements :



https://reactjs.org/docs/refs-and-the-dom.html



But today we have hooks together with functional components.
and we are using useRef hook.



also, this brings to us new patterns. using ref to contain callbacks, or any data we want to preserve (kind of state) but without the need to rerender.
its a powerful API and also shows up in the docs:



https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables



so now ref can be used for:




  1. store mutable data


  2. kind of memoization




but these docs contradict each other. and causing many mistakes, and conflicts in development teams.



the doc says 2 different things and its a problem.



so, what is the right thing to do in a scenario like that?




const MyComponent = (props) => {
const [myMap1, _] = useState(new Map()); // 1.
const myMap2 = useMemo(()=> new Map(), []); // 2.
const myMap3 = useRef(new Map()); // 3.

...
};


More From » reactjs

 Answers
2

useMemo is a declarative performance optimization technique.


Declarative, as it relies on state or props dependencies from the surrounding scope belonging to a particular render and automatically (re)creates the memoized value. We don't have to tell useMemo to do that.


useRef is a mutable storage box for any values, e.g. value updates independent from current render scope.


useRef does not have any dependencies, so no value is automatically changed. You have to do that manually by writing ref.current = ... (DOM nodes are an exception).
That is why you could see useRef as an escape hatch into the imperative world.


Now, we could try to mix their usage interchangeably for storage, like:
// instead of 
const val = useMemo(() => 42, [myDep]); // 42 stands for some complex calculation
// do this
const ref = useRef();
ref.current = 42 // assign 42 imperatively to ref somewhere in render

Or even replace useRef by useState:
const [ref] = useState({current:null});
ref.current = "hello";

Disadvantage: we are back in old jQuery age :-). Operations have to be set imperatively, meaning more manual work and possible mistakes. Immutable value manipulations are also much more predictable than mutations (incl. other benefits). That is, why nearly everything in React is immutable.


Instead, it makes sense to stay declarative when possible (React idiomatic) and use the intended, optimized tools for their specific case:



  • useState for immutable values in a declarative manner, triggers re-render

  • useMemo for declarative memoization of costly values derived from state and props

  • useRef for mutable values or DOM nodes - independent of render closure scope, no need for deps, doesn't trigger re-render, more manual imperative work


[#3746] Monday, May 18, 2020, 4 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
wilson

Total Points: 27
Total Questions: 93
Total Answers: 93

Location: Tajikistan
Member since Sun, Aug 29, 2021
3 Years ago
wilson questions
Tue, Aug 9, 22, 00:00, 2 Years ago
Wed, May 11, 22, 00:00, 2 Years ago
Wed, May 13, 20, 00:00, 4 Years ago
;