1
头图

The text starts here~

Overview

To fix "Warning: Can't perform a React state update on an unmounted component" , declare a isMounted boolean in your useEffect hook to track whether the component is installed. The state of a component is only updated when the component is mounted.

 import {useState, useEffect} from 'react';

const App = () => {
  const [state, setState] = useState('');

  useEffect(() => {
    // 👇️ set isMounted to true
    let isMounted = true;

    async function fetchData() {
      const result = await Promise.resolve(['hello', 'world']);

      // 👇️ only update state if component is mounted
      if (isMounted) {
        setState(result);
      }
    }

    fetchData();

    return () => {
      // 👇️ when component unmounts, set isMounted to false
      isMounted = false;
    };
  }, []);

  return (
    <div>
      <h2>State: {JSON.stringify(state)}</h2>
    </div>
  );
};

export default App;
When we try to update the state of an unmounted component, the warning "Cannot perform React state update on unmounted component" appears.

isMounted

A straightforward way to get rid of this warning is to use isMounted boolean in the useEffect hook to track whether the component is mounted or not.

In useEffect we initialize isMounted with a boolean value of true .

Our fetchData function performs some asynchronous task, most commonly an API request, and updates state based on the response.

Note, however, that we only update the state when the isMounted variable is set to true .

 async function fetchData() {
  const result = await Promise.resolve(['hello', 'world']);

  // 👇️ only update state if component is mounted
  if (isMounted) {
    setState(result);
  }
}

This helps us avoid warnings because if the component isn't mounted, we don't update the state.

The function returned from the useEffect hook will be called when the component is unmounted.

 return () => {
  // 👇️ when component unmounts, set isMounted to false
  isMounted = false;
};

We set the isMounted variable to false , indicating that the component is no longer mounted. fetchData卸载时被调用, if代码块isMounted false

 async function fetchData() {
  const result = await Promise.resolve(['hello', 'world']);

  // 👇️ only update state if component is mounted
  if (isMounted) {
    setState(result);
  }
}

extract

If you do this frequently, you can extract the logic into reusable hooks.

 import {useState, useEffect, useRef} from 'react';

// 👇️ extract logic into reusable hook
function useIsMounted() {
  const isMounted = useRef(false);

  useEffect(() => {
    isMounted.current = true;

    return () => {
      isMounted.current = false;
    };
  });

  return isMounted;
}

const App = () => {
  const [state, setState] = useState('');

  // 👇️ use hook
  const isMountedRef = useIsMounted();

  useEffect(() => {
    async function fetchData() {
      const result = await Promise.resolve(['hello', 'world']);

      // 👇️ only update state if component is mounted
      if (isMountedRef.current) {
        setState(result);
      }
    }

    fetchData();
  }, [isMountedRef]);

  return (
    <div>
      <h2>State: {JSON.stringify(state)}</h2>
    </div>
  );
};

export default App;

useRef() hook can be passed an initial value as a parameter. The hook returns a mutable ref object whose .current property is initialized to the passed parameter.

We track whether the component is mounted in the useIsMounted hook, just as we did directly in the component's useEffect hook.

It should be noted that in the fetchData function, we have to check the value of ---152f224bb6d5773b89f6a986be211eaf isMountedRef.current , because ref ref the current attribute The actual value of ref .


chuck
300 声望41 粉丝