Differences between `useRef` and ref variable in ReactJS
Asked Answered
C

2

8

I have this

const CompA = () => {
  let _input;
  return (
    <input ref={el => _input = el} type="text" />
  );
}

And this

const CompB = () => {
  const _input = useRef(null);
  return (
    <input ref={_input} type="text" />
  );
}

Two _input is the ref object of the input tag and I can't find the differences between them.

My question is: What are the differences between two _input and which _input is better?

Chamaeleon answered 12/6, 2019 at 0:35 Comment(0)
H
12

The two ways of defining, refs are not equivalent.

Consider the first example

const CompA = () => {
  let _input;
  return (
    <input ref={el => _input = el} type="text" />
  );
}

In this example, whenever, CompA re-renders, as new variable _input is created and for instance if you have a useEffect in CompA which is meant to run on initial render and it executes something at an interval using this ref variable it would lead to inconsitencies.

Now consider second case

const CompA = () => {
  const _input = useRef(null);
  return (
    <input ref={_input} type="text" />
  );
}

In this case, even though the _input variable is created on each render, useRef ensures that it receives the same reference that it receives the first time and not initialise it again. useRef is the right way to define refs for functional Components. For class components you can use createRef or the callback pattern you mention

Heterogenous answered 12/6, 2019 at 5:34 Comment(1)
This is especially applicable when the value is used in a dependency array of a useEffect() hook. Using a variable instead of a ref can cause unintended extra triggerings of the useEffect() hook in question.Butterfat
D
3

From the docs:

This works because useRef() creates a plain JavaScript object. The only difference between useRef() and creating a {current: ...} object yourself is that useRef will give you the same ref object on every render.

In other words, useRef will keep the reference on every render/update, by changing props or state. On the other side, simple ref as variable will be erased at every component cycle.

Doolie answered 12/6, 2019 at 0:48 Comment(1)
This means that const ref = useRef(1) is equal to const ref = useMemo(() => ({ current: 1 }), [])Prolix

© 2022 - 2024 — McMap. All rights reserved.