The useRef
hook in React is a powerful tool for managing mutable values and accessing DOM elements. It allows you to create a mutable ref object that persists across renders without causing re-renders. This can be particularly useful for scenarios where you need to store a value between renders or interact with DOM elements imperatively.
const [name, setname] = useState('')
const [render, setrender] = useState(0)
useEffect(() => {
setrender(prev => prev + 1)
}, [name])
return ( <>
<input type="text" value={name} onChange={(e) => setname(e.target.value)} />
<h2>My name is {name}</h2>
<p>You change name value {render} times</p>
</> )
When we use useState it re-render components when state value change but some times we cannot re-render component when state variable value change, so that time we use useRef, it cannot re-render component when ref value change but it change only ref variable value, useRef is mutable.
useRef is completely separate from re-render components cycle, it is similar to useState.
const [name, setname] = useState('')
const render = useRef(0)
useEffect(() => {
render.current = render.current + 1
})
return ( <>
<input type="text" value={name} onChange={(e) => setname(e.target.value)} />
<h2>My name is {name}</h2>
<p>You change name value {render.current} times</p>
</> )
useRef also use for handle DOM objects, when we create a button that onClick focus goes to input field like a javascript DOM event, we create using with useRef in functional components.
const [name, setname] = useState('Parth')
const username = useRef()
return (<>
<input ref={username} value={name}
onChange={(e) => setname(e.target.value)} disabled={true} />
<h2>My name is {name}</h2>
<button onClick={() => {
username.current.attributes.removeNamedItem('disabled')
username.current.focus()
}}>Edit ✎</button>
<button onClick={() => {
username.current.setAttribute("disabled", "true")
}}>Edited ✔</button>
</>)
When we want to track the number of times a component renders without causing re-renders, we can use useRef
. Here's an example:
import React, { useState, useRef, useEffect } from 'react';
const RenderCountExample = () => {
const [name, setName] = useState('');
const renderCount = useRef(0);
useEffect(() => {
renderCount.current++;
}, [name]);
return (
<>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<h2>My name is {name}</h2>
<p>You've changed the name value {renderCount.current} times</p>
</>
);
};
In this example, renderCount
is a ref object initialized with a value of 0. We increment its value every time the name
state changes, and it persists across renders without causing the component to re-render.
Using useRef
allows us to manage mutable values without triggering re-renders, making it suitable for scenarios where we need to track values across renders.
useRef
can also be used to access DOM elements directly. Here's an example:
import React, { useState, useRef } from 'react';
const FocusInputExample = () => {
const [name, setName] = useState('Parth');
const inputRef = useRef();
const handleEdit = () => {
inputRef.current.removeAttribute('disabled');
inputRef.current.focus();
};
const handleEdited = () => {
inputRef.current.setAttribute('disabled', 'true');
};
return (
<>
<input
ref={inputRef}
value={name}
onChange={(e) => setName(e.target.value)}
disabled
/>
<h2>My name is {name}</h2>
<button onClick={handleEdit}>Edit ✎</button>
<button onClick={handleEdited}>Edited ✔</button>
</>
);
};
In this example, we use useRef
to create a ref for the input field. We can then imperatively focus on the input field or modify its attributes without causing re-renders.
useRef
Objective: Create a component that focuses on an input field and enables/disables it based on button clicks.
Create a FocusInput Component:
Create a new file FocusInput.jsx
and define a component that includes an input field and two buttons.
Implement useRef
:
Utilize the useRef
hook to access the input field directly.
Handle Button Clicks:
Implement functions to handle button clicks:
Render the Component:
Import and render the FocusInput
component in your application to test its functionality.