0
votes

Annoying warning is logged in console while loading the home screen. How can I remove this warning, I have created a const isMounted = useRef(null); How does it work and where should i need to use this ?

  isMounted.current = true;
  return () => {
    // executed when unmount
    isMounted.current = false;
  }

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. in Home (created by Context.Consumer) in Route (at App.js:21) in Switch (at App.js:20) in Router (created by BrowserRouter) in BrowserRouter (at App.js:17) in App

Home.js

const isMounted = useRef(null);

  useEffect(() => {
    const fetchData = async () => {
      try {
        const res = await Axios.get('http://localhost:8000/service/players');
        setPlayerList(res.data.players);
        setSearchResults(res.data.players);
        showDeleteIcon(privilege);
      } catch (e) {
        console.log(e);
      }
    }
    fetchData();
  }, []);
1

1 Answers

1
votes

You can use a second effect to update the value if the isMounted ref. Then, before calling setState, you can check isMounted.current to see if you're still mounted.

const isMounted = useRef(false);

useEffect(() => {
  isMounted.current = true;
  return () => isMounted.current = false;
}, []);

useEffect(() => {
  const fetchData = async () => {
    try {
      const res = await Axios.get('http://localhost:8000/service/players');
      if (isMounted.current) {
        setPlayerList(res.data.players);
        setSearchResults(res.data.players);
        showDeleteIcon(privilege);
      }
    } catch (e) {
      console.log(e);
    }
  }
  fetchData();
}, []);

The .current property is just the way that React refs work. I'm really not sure why they did it that way, but essentially that's how you get/set the value. It's different from state because state changes cause re-renders whereas ref updates do not.

A better approach that wouldn't need the ref and new effect may be to use the callback version of the state setters, since React might avoid calling your callback if the component is unmounted:

useEffect(() => {
  const fetchData = async () => {
    try {
      const res = await Axios.get('http://localhost:8000/service/players');
      setPlayerList(() => res.data.players);
      setSearchResults(() => res.data.players);
      showDeleteIcon(() => privilege);
    } catch (e) {
      console.log(e);
    }
  }
  fetchData();
}, []);