useRef is one of the standard hooks provided by React. It will return an object that you can use during the whole lifecycle of the component.
The main use case for the useRef hook is to access a DOM child directly.
Although accessing the DOM is the main use case, it doesn’t mean it’s the only one! useRef can also be very useful to hold a mutable value across different renders of your component.
it’s often quite handy when using external libraries that weren’t made with React in mind. You can initialize a new ref inside a component with the following code
const yourRef = useRef();
-If we tried to count how many times our application renders using the useState Hook, we would be caught in an infinite loop since this Hook itself causes a re-render. for avoid this, we shold use the useRef Hook.
Use useRef to track your React application renders.
import { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
function App() {
const [inputValue, setInputValue] = useState("");
const count = useRef(0);
useEffect(() => {
count.current = count.current + 1;
});
return (
<>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<h1>Render Count: {count.current}</h1>
</>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
It's like doing this: const count = {current: 0}. We can access the count by using count.current.
Above example code run on your computer and try typing in the input to see the application render count increase.
In React, we can add a ref attribute to an element to access it directly in the DOM.
Use useRef to focus the input
import { useRef } from "react";
import ReactDOM from "react-dom";
function App() {
const inputElement = useRef();
const focusInput = () => {
inputElement.current.focus();
};
return (
<>
<input type="text" ref={inputElement} />
<button onClick={focusInput}>Focus Input Value</button>
</>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
The useRef Hook can also be used to keep track of previous state values. This is because we are able to persist useRef values between renders.
import { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
function App() {
const [inputValue, setInputValue] = useState("");
const previousInputValue = useRef("");
useEffect(() => {
previousInputValue.current = inputValue;
}, [inputValue]);
return (
<>
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
<h2>Current Input Value: {inputValue}</h2>
<h2>Previous Input Value: {previousInputValue.current}</h2>
</>
);
}
ReactDOM.render(<App />, document.getElementById('root'));
This time we use a combination of useState, useEffect, and useRef to keep track of the previous state.
In the useEffect, we are updating the useRef current value each time the inputValue is updated by entering text into the input field.
Above example code Run this on your computer and try typing in the input to see the Current Input Value and Previous Input Value.
-To developers that are new to React, it might be tempting to use this hook to access any DOM element and use JavaScript to get your code to work.
- However, during my time working as a React developer, I only needed to use references a couple of times. By default, we should try to solve the problem using React's state and props, which will make our codebase much easier to maintain.
- React's state and prop system is the best and most reliable way to communicate between components. As developers, we're best served using this and only falling back to native JavaScript for special use cases like the ones I described above.
React's useRef hook is a great tool to persist data between renders without causing a rerender and to manipulate the DOM directly.