useRef
useRef
is a React Hook that lets you reference a value that’s not needed for rendering 😀
if you want to update your UI with that value you should use useState because whenever a state changes useState runs the re-render 😊
let’s understand it in detail:🥳
Usage
1. Referencing a value with a ref
Call useRef
at the top level of your component to declare one or more refs.
import { useRef } from 'react';
function App() {
const countRef = useRef(0);
// ...
useRef
returns a ref object with a single current
property initially set to the initial value you provided.
Here we’ve provided 0
as an initial value to the countRef.
on the next renders, you can change its current property to store information and read it later.
Changing a ref does not trigger a re-render. This means refs are perfect for storing information that doesn’t affect the visual output of your component.
let’s take an example
Here if you click on the button Increase The Count
then you’ll see the value does not change it’s the same as before 0
However, you’ll see the updated value in the console.
This is because the setting ref.current
does not trigger a re-render.
To update the value in UI you should use useState instead of useRef.
But now here we are breaking a rule of react that is
Do not write or read ref.current
during rendering.
function MyComponent() {
// ...
// 🚩 Don't write a ref during rendering
myRef.current = 123;
// ...
// 🚩 Don't read a ref during rendering
return <h1>{myOtherRef.current}</h1>;
}
here we are breaking the rule that don’t read ref.curretn
during rendering.
If you have to read or write something during rendering, use state instead.
When you break these rules, your component might still work, but most of the newer features we’re adding to React will rely on these expectations.
2. Manipulating the DOM with a ref
It’s common to use a ref to manipulate the DOM.
First, declare a ref object with an initial value of null
:
import * as React from 'react';
import { useRef } from 'react';
export default function App() {
const headingRef = useRef(null);
Then attach your ref attribute to the JSX of the DOM node you want to manipulate:
// ...
<h1 ref={headingRef} onClick={handleClick}>
here is the complete code
Here we are adding the headingRef
attribute to the h1
tag and on handleClick
we are changing the color of h1.
we can get all the property by using .current
and after that we can perform whatever the actions we want.
Avoiding recreating the ref contents
React saves the initial ref value once and ignores it on the next renders.
function Video() {
const playerRef = useRef(new VideoPlayer());
// ...
Although the result of new VideoPlayer()
is only used for the initial render, you’re still calling this function on every render. This can be wasteful if it’s creating expensive objects.
To solve it, you may initialize the ref like this instead:
function Video() {
const playerRef = useRef(null);
if (playerRef.current === null) {
playerRef.current = new VideoPlayer();
}
// ...
Normally, writing or reading ref.current
during render is not allowed. However, it’s fine in this case because the result is always the same, and the condition only executes during initialization so it’s fully predictable.
Troubleshooting
If you try to pass a ref
to your own component like this:
const inputRef = useRef(null);
return <MyInput ref={inputRef} />;
You might get an error in the console:
* Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
By default, your own components don’t expose refs to the DOM nodes inside them.
To fix this, find the component that you want to get a ref to:
export default function MyInput({ value, onChange }) {
return (
<input
value={value}
onChange={onChange}
/>
);
}
And then wrap it in forwardRef
like this:
(I’ll write a blog post about forwardRef soon 😊)
import { forwardRef } from 'react';
const MyInput = forwardRef(({ value, onChange }, ref) => {
return (
<input
value={value}
onChange={onChange}
ref={ref}
/>
);
});
export default MyInput;
Then the parent component can get a ref to it.
Here is my article on forwardRef
Hope you like it 🤗
Happy coding!
want to give suggestions:-
Email me at nidhisharma639593@gmail.com