React useEffect causing: Can't perform a React state update on an unmounted component

后端 未结 3 1959
野性不改
野性不改 2020-12-29 03:21

When fetching data I\'m getting: Can\'t perform a React state update on an unmounted component. The app still works, but react is suggesting I might be causing a memory leak

相关标签:
3条回答
  • 2020-12-29 03:27

    You can try this set a state like this and check if your component mounted or not. This way you are sure that if your component is unmounted you are not trying to fetch something.

    const [didMount, setDidMount] = useState(false); 
    
    useEffect(() => {
       setDidMount(true);
       return () => setDidMount(false);
    }, [])
    
    if(!didMount) {
      return null;
    }
    
    return (
        <ArtistProfileContainer>
          <AlbumContainer>
            {artistData ? artistData.artistAlbums.items.map(album => {
              return (
                <AlbumTag
                  image={album.images[0].url}
                  name={album.name}
                  artists={album.artists}
                  key={album.id}
                />
              )
            })
            : null}
          </AlbumContainer>
        </ArtistProfileContainer>
      )
    

    Hope this will help you.

    0 讨论(0)
  • 2020-12-29 03:28

    For me, clean the state in the unmount of the component helped.

     const [state, setState] = useState({});
    
    useEffect(() => {
        myFunction();
        return () => {
          setState({}); // This worked for me
        };
    }, []);
    
    const myFunction = () => {
        setState({
            name: 'Jhon',
            surname: 'Doe',
        })
    }
    
    
    0 讨论(0)
  • 2020-12-29 03:46

    Sharing the AbortController between the fetch() requests is the right approach.
    When any of the Promises are aborted, Promise.all() will reject with AbortError:

    function Component(props) {
      const [fetched, setFetched] = React.useState(false);
      React.useEffect(() => {
        const ac = new AbortController();
        Promise.all([
          fetch('http://placekitten.com/1000/1000', {signal: ac.signal}),
          fetch('http://placekitten.com/2000/2000', {signal: ac.signal})
        ]).then(() => setFetched(true))
          .catch(ex => console.error(ex));
        return () => ac.abort(); // Abort both fetches on unmount
      }, []);
      return fetched;
    }
    const main = document.querySelector('main');
    ReactDOM.render(React.createElement(Component), main);
    setTimeout(() => ReactDOM.unmountComponentAtNode(main), 1); // Unmount after 1ms
    <script src="//cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.development.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.development.js"></script>
    <main></main>

    0 讨论(0)
提交回复
热议问题