'useEffect is not called when dependencies change
import React, { useState, useEffect, useRef } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
const [minus, setMinus] = useState(3);
const ref = useRef(null);
const handleClick = () => {
setMinus(minus - 1);
};
console.log(
"--> ref and state",
ref.current?.innerHTML ?? ref.current,
minus
);
// first useEffect
useEffect(() => {
console.log(`denp[ref.current] >`, ref.current?.innerHTML ?? ref.current);
}, [ref.current]);
// second useEffect
useEffect(() => {
console.log(`denp[minus]>`, ref.current?.innerHTML ?? ref.current);
}, [minus]);
return (
<div className="App">
{(minus >= 0 || minus <= -5) && <h1 ref={ref}>num: {minus}</h1>}
<button onClick={handleClick}>minus</button>
</div>
);
}
export default App;
On the first render: the first useEffect is run and log out: denp[ref.current] > num: 3
I press the button, the state minus is updated to 2, the component is re-rendered
On the second render: the first useEffect is run and log out: denp[ref.current] > num: 2
I press the button, the state minus is updated to 1, the component is re-rendered
On the third render: the first useEffect is not run anymore
Why the first useEffect does not run on the third render?
Live code here: https://codesandbox.io/s/brave-mayer-3f8zsl
Solution 1:[1]
if you really want to use ref as a dependency, so use ref.current.innerHTML instead of ref.current. I teseted It with ref.current.innerHTML and it worked for me hope helping you
Solution 2:[2]
I guess you should not rely on the ref as a dependency, since it is not triggering updates, as it is said here.
Solution 3:[3]
If you are using Next.JS (maybe applies to any SSR), I would suggest also setting the dependency to ref.current?.innerHTML and then it will work.
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 | Mohammad |
Solution 2 | TheTisiboth |
Solution 3 | howard |