It is usually advised to avoid using refs in React for anything that can be done declaratively, but there are few cases when you need to imperatively modify DOM element. One of it, to access or modify a child outside of the typical dataflow, like managing focus, selecting text or media playback.
How To
Ref attributes may not be used on function components because they don't have instances, but React Hooks introduced a function useRef()
, which holds and returns a mutable object .current
.
The function takes the optional initial value as an argument, and if you forgot to pass it, don't worry, you will be able to do it later.
const refContainer = useRef(initialValue);
And the returned mutable object exists through the whole lifetime of the component
The best ilustration how useRef()
works would be with the example of input
field manipulation:
function App() {
const inputRef = React.useRef();
return (
<>
<input ref={inputRef} />
<button onClick={() => inputRef.current.focus()} />
</>
)
}
The inputRef
holds the reference to the DOM element input
, and all properties of the element can be accessed directly through the inputRef.current
. As a side effect of clicking the button, we can manipulate the input
, like setting it on focus inputRef.current.focus()
.
Not only for DOM
As the hook holds a mutable object, we can use it not only for accessing the DOM elements, but to hold any value: strings, numbers, other objects, functions. You can store previous state values inside it in case you need to access it later.
The example below demonstrates how the number value is stored inside the mutable object, and on every component render it updates, increments and renders the count to the browser. Now you will know how many times your component was re-rendered unnecessarily :)
function App() {
const ref = React.useRef(0);
React.useEffect(() => {
ref.current += 1;
});
return (
<div>{ref.current}</div>
)
}
Also, need to keep in mind, that changes to the mutable object .current
does not notify you, so the component will not re-render when you modify the object.
Final notes
useRef()
creates a simple JavaScript object, I think it's a great hook for holding and accessing not only refs but any data like we do it with the fields of the class components.
Top comments (0)