0

Hy, I login the user from Login.js and update the state in App.js using useContext hook. But it giving me that warning : Can't perfom a React state update on an unamounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in useEffect cleanup function

Login.js

import {LoginContext} from '../../App'
const Login = ({ navigation }) => {
     // some other states 
     const {user, setUser} = useContext(LoginContext)
     
        const login = async () => {
        if (name != '' && password != '') {
            const login_Credentials = new FormData();
            login_Credentials.append('username', name);
            login_Credentials.append('password', password);
            setPress(true)
            await axios({
                method: 'POST',
                url: api + 'login/',
                data: login_Credentials,
                headers: { 'Content-Type': 'multipart/form-data' }
            }).then(async function (response) {
                if (response.data.Success == true) {
                    const token = response.data.token.toString();
                    const super_user_status = response.data.super_user_status.toString();
                    const isLoggedIn = "1"
                    console.log('Logged In and set Storgae')
                    await AsyncStorage.multiSet([['isLoggedIn',isLoggedIn],['token', token], ['super_user_status', super_user_status]])
                    setUser(true) //context value updated
                    setName('')
                    setPassword('')
                    setPress(false)
                } else if (response.data.Success == false) {
                    setPress(false)
                    setErrorMsg(response.data.Error)
                    setName('')
                    setPassword('')
                    
                }
            }).catch(function (response) {
                setErrorMsg('Server Error 404');
                setPress(false)

            })
        } else {
            setErrorMsg('Please Enter Username/Password.')
        }
    }




}

App.js

export const LoginContext = React.createContext();

const App = () => {
  const [user, setUser] = useState(false) //use for context
  const [role, setRole] = useState('seller')

  useEffect(()=>{ 
    getKeysData(dataKeys)
  },[]) 
  const dataKeys = ['token', 'super_user_status', 'isLoggedIn'];    
  const getKeysData = async (keys) => {
    const stores = await AsyncStorage.multiGet(keys);
    const aData = await Promise.all(stores.map(([key, value]) => ({[key]: value})))
    const token = aData[0]['token']
    const super_user_status = aData[1]['super_user_status']
    const isLoggedIn = aData[2]['isLoggedIn']
    }
  //AsyncStorage.clear()
return (
 <NavigationContainer>
    <LoginContext.Provider value={{user,setUser}} >
      { user == false ?
        <AuthStackScreen />
        :
        <BuyerDashboardStackScreens />
      }
      </LoginContext.Provider>
      
    </NavigationContainer>
  );
};

Adil Ijaz
  • 312
  • 1
  • 5
  • 16
  • Duplicate: [Can't perform a React state update on an unmounted component](https://stackoverflow.com/questions/53949393/cant-perform-a-react-state-update-on-an-unmounted-component) –  Jun 02 '21 at 09:40

2 Answers2

0

you do not cancel the subscription of useEffect that's why you are getting this warning you can unsubscribe like this

 useEffect(()=>{ 
  const unSub= getKeysData(dataKeys)
  return unSub;
  },[]) 
shammi
  • 1,301
  • 1
  • 10
  • 25
0

Assuming that <Login> is inside <AuthStackScreen />, at first glance this looks like it is because you update the user using your setUser function that you got from subscribing to the context, and then you immediately update state that appears to be local to Login.js. The effect that this has is after changing the user, <App> re-renders, causing this

 { user == false ?
        <AuthStackScreen />
        :
        <BuyerDashboardStackScreens />
 }

to be reevaluated, at which point <BuyerDashboardStackScreens /> is rendered instead. However, once this has occurred, React then attempts to update the local state in Login.js of name, password, press since you have written

setName('')
setPassword('')
setPress(false)

At this point, the instance of <AuthStackScreen /> and thus the instance of <Login> have already been unmounted, so you can't update its state anymore. I think this is the reason it says you're attempting to perform a state update on an unmounted component.

Nicholas R
  • 36
  • 3