72746

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

<h3>Question</h3>

I am creating a website that lists several open job positions.

I want to GET all the job positions once the component mounts. Therefore, I used useEffect. I am setting the state inside useEffect, which I think is causing the error:

<blockquote>

Warning: Can't perform a React state update on an unmounted component.

</blockquote>

I would like to know how I can fix this warning. I am not understanding why I cannot set the state inside useEffect

My component

function MyComponent({changeType}) { const [user, setUser] = React.useState([]); const [positions, setPositions] = React.useState([]); async function getAllPositions(){ let response = await axios("http://www.localhost:3000/api/v1/positions"); setPositions(response.data) } useEffect( ()=> { let jwt = window.localStorage.getItem('jwt') let result = jwtDecode(jwt) setUser(result) changeType() # It is a function passing props to the parent of "MyComponent" getAllPositions() }, [], ) return( <div> Something </div> ) }
<h3>Answer1:</h3>

You should check if component is still mounted before update state after an async call

useEffect( ()=> { let unmounted = false async function getAllPositions(){ let response = await axios("http://www.localhost:3000/api/v1/positions"); if(!unmounted) setPositions(response.data) } let jwt = window.localStorage.getItem('jwt') let result = jwtDecode(jwt) setUser(result) getAllPositions() return () => { unmounted = true } }, [])
<h3>Answer2:</h3>

@Alexander Vidaurre Arroyo's answer is correct. You're essentially need to ensure that state isn't being updated when the component is unmounted.

I tried rewriting his answer a little bit in the spirit of hooks to see how you can extract some of the approach of checking for if a component is mounted to determine if state should be updated.

import React, { useCallback, useRef, useState } from 'react'; const useIsMounted = () => { const isMounted = useRef(false); useEffect(() => { isMounted.current = true; return () => isMounted.current = false; }, []); return () => isMounted.current; }; const useAsyncState = (defaultValue) => { const isMounted = useIsMounted(); const [value, setRawValue] = useState(defaultValue); const setValue = useCallback((newValue) => { if (isMounted()) { setRawValue(newValue); } }, []); return [value, setValue]; }; const getAllPositions = async () => { const response = await axios("http://www.localhost:3000/api/v1/positions"); return response.data; }; function MyComponent() { const [user, setUser] = useAsyncState([]); const [positions, setPositions] = useAsyncState([]); useEffect(async () => { const jwt = window.localStorage.getItem('jwt'); const result = jwtDecode(jwt); setUser(result); setPositions(await getAllPositions()); }, [setPositions, setUser]); return( <div> Something </div> ); }

来源:https://stackoverflow.com/questions/59524063/useeffect-cant-perform-a-react-state-update-on-an-unmounted-component

Recommend