patternjavascriptreactCritical
Make React useEffect hook not run on initial render
Viewed 0 times
hookrenderreactnotrunuseeffectinitialmake
Problem
According to the docs:
We can use the new
As you can see in the example below,
componentDidUpdate() is invoked immediately after updating occurs. This method is not called for the initial render.We can use the new
useEffect() hook to simulate componentDidUpdate(), but it seems like useEffect() is being ran after every render, even the first time. How do I get it to not run on initial render?As you can see in the example below,
componentDidUpdateFunction is printed during the initial render but componentDidUpdateClass was not printed during the initial render.function ComponentDidUpdateFunction() {
const [count, setCount] = React.useState(0);
React.useEffect(() => {
console.log("componentDidUpdateFunction");
});
return (
componentDidUpdateFunction: {count} times
{
setCount(count + 1);
}}
>
Click Me
);
}
class ComponentDidUpdateClass extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
};
}
componentDidUpdate() {
console.log("componentDidUpdateClass");
}
render() {
return (
componentDidUpdateClass: {this.state.count} times
{
this.setState({ count: this.state.count + 1 });
}}
>
Click Me
);
}
}
ReactDOM.render(
,
document.querySelector("#app")
);
Solution
We can use the
If we want the effect to run in the same phase that
Example
useRef hook to store any mutable value we like, so we could use that to keep track of if it's the first time the useEffect function is being run.If we want the effect to run in the same phase that
componentDidUpdate does, we can use useLayoutEffect instead.Example
const { useState, useRef, useLayoutEffect } = React;
function ComponentDidUpdateFunction() {
const [count, setCount] = useState(0);
const firstUpdate = useRef(true);
useLayoutEffect(() => {
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
console.log("componentDidUpdateFunction");
});
return (
componentDidUpdateFunction: {count} times
{
setCount(count + 1);
}}
>
Click Me
);
}
ReactDOM.render(
,
document.getElementById("app")
);
Context
Stack Overflow Q#53253940, score: 317
Revisions (0)
No revisions yet.