'Does react retain event on subsequent rerenders after assigning it in useEffect?
React says it reregisters event on every rerender on below occasion:
function App() {
const [count, setCount] = useState(0);
const registerhandler = (event) => {
setCount((prev) => prev + 1);
}
return (
<>
<p>{count}</p>
<button type="button" id="button1" onClick={registerhandler}>Click</button>
</>
)
}
What about the registering event in useEffect, does it retain event between rerenders, or how does it work:
function App() {
const [count, setCount] = useState(0);
useEffect(() => {
document.getElementById('button1').addEventListener('click', () => {
setCount((prevCount) => prevCount + 1);
})
}, []);
return (
<>
<p>{count}</p>
<button type="button" id="button1">Click</button>
</>
)
}
Solution 1:[1]
The second would apply only 1 callback handler once when the component mounts, but querying the DOM is generally considered anti-pattern in react.
If you want to bind an event handler once then either memoize the callback:
function App() {
const [count, setCount] = useState(0);
const registerhandler = useCallback((event) => {
setCount((prev) => prev + 1);
}, []);
return (
<>
<p>{count}</p>
<button type="button" onClick={registerhandler}>
Click
</button>
</>
);
}
Or use a React ref to access the underlying DOMNode: (don't forget to clean up the effect and remove the listener!)
function App() {
const [count, setCount] = useState(0);
const ref = useRef();
useEffect(() => {
const buttonRef = ref.current;
const handler = () => {
setCount((prevCount) => prevCount + 1);
};
buttonRef.addEventListener('click', handler);
return () => {
buttonRef.removeEventListener('click', handler);
};
}, []);
return (
<>
<p>{count}</p>
<button ref={ref} type="button">Click</button>
</>
)
}
Unless you've an actual performance issue though, just use the first example where the handler is created each render.
function App() {
const [count, setCount] = useState(0);
const registerhandler = (event) => {
setCount((prev) => prev + 1);
};
return (
<>
<p>{count}</p>
<button type="button" onClick={registerhandler}>
Click
</button>
</>
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Drew Reese |
