Each time Comp
re-renders, rand
will be a different value. Will it trigger the useEffect
?
function Comp({}) {
const rand = Math.random();
useEffect(() => {
// do stuff
}, [rand])
}
CodePudding user response:
The variable in the dependencies's array is not tied to the fact it's a state
set with some setState
. As long as it's in the array and it changes, useEffect
's callback gets called again. Now, how useEffect
notices that change? Well it does a diff whenever the component render. And only a state
set with a setState
can re-render a component.
I made up an example to explain more. If you already understood the mechanisme, you could stop here, and go build your amazing product with React :). Otherwise, keep reading.
Say we have this component:
export default function Comp() {
let rand = Math.random();
useEffect(() => {
console.log("Hello Word");
}, [rand]);
return (
<button onClick={() => { rand = Math.random() }}>
New value
</button>
);
}
We should have Hello Word
logged in the console when the component render first time, and every time rand
changes. Clicking on that button
changes rand
, but we won't have a new, log, because there isn't any re-render as no state
has changed. And since there isn't a re-render, useEffect
is not aware of the change.
Now let's take this same component, and change it a little bit:
export default function Comp() {
const [state, setState] = useState(true); // new line added
let rand = Math.random();
useEffect(() => {
console.log("Hello Word");
}, [rand]);
// notice that the click handler has changed
return (
<button onClick={() => setState(!state)}>
New value
</button>
);
}
Now every time you click on the button the component re-render, because we are setting a state
with setState
, and while re-rendering if the value of rand
changes from the previous one, we will get a new log.
But since we are using
Math.random()
we could have two similar values inrand
for two renders, in which case there wouldn't be a new log.
CodePudding user response:
Every time that the component will be re-render the Math.random
method will be evaluated, so it will cause the useEffect
to run again (with the exception that rand
has changed).
Instead, if it will be just a constant, it not re-run the useEffect
.
CodePudding user response:
if you console.log("hello") inside the useEffect, you'll see that you only see two console's showing "hello"(because of componentWillMount and componentDidMount). This means that, your component will only re-render if a value of a state variable has changed or props that is been passed to this is changed (offcourse the props passed have to be a state or else it won't rerender).
Conclusion : Only change in value of state or props in a component re-renders the component.