HiveBrain v1.2.0
Get Started
← Back to all entries
snippetreactCritical

With useEffect, how can I skip applying an effect upon the initial render?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
applyingeffectupontheinitialrenderwithcanhowuseeffect

Problem

With React's new Effect Hooks, I can tell React to skip applying an effect if certain values haven't changed between re-renders - Example from React's docs:

useEffect(() => {
  document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes


But the example above applies the effect upon initial render, and upon subsequent re-renders where count has changed. How can I tell React to skip the effect on the initial render?

Solution

As the guide states,

The Effect Hook, useEffect, adds the ability to perform side effects from a function component. It serves the same purpose as componentDidMount, componentDidUpdate, and componentWillUnmount in React classes, but unified into a single API.

In this example from the guide it's expected that count is 0 only on initial render:

const [count, setCount] = useState(0);


So it will work as componentDidUpdate with additional check:

useEffect(() => {
  if (count)
    document.title = `You clicked ${count} times`;
}, [count]);


This is basically how custom hook that can be used instead of useEffect may work (updated for the use with strict mode):

function useDidUpdateEffect(fn, inputs) {
  const isMountingRef = useRef(false);

  useEffect(() => {
    isMountingRef.current = true;
  }, []);

  useEffect(() => {
    if (!isMountingRef.current) {
      return fn();
    } else {
      isMountingRef.current = false;
    }
  }, inputs);
}

Code Snippets

const [count, setCount] = useState(0);
useEffect(() => {
  if (count)
    document.title = `You clicked ${count} times`;
}, [count]);
function useDidUpdateEffect(fn, inputs) {
  const isMountingRef = useRef(false);

  useEffect(() => {
    isMountingRef.current = true;
  }, []);

  useEffect(() => {
    if (!isMountingRef.current) {
      return fn();
    } else {
      isMountingRef.current = false;
    }
  }, inputs);
}

Context

Stack Overflow Q#53179075, score: 248

Revisions (0)

No revisions yet.