ZeevhY Org.
ZeevhY Org.

Reputation: 365

UseAsyncstorage causes infinit loop in react native

Problem is that my component content rendering in an infinite loop.

const CustomDrawer =({navigation})=>{
    const [logged_in , setLoggedIn]= useState(false)

    useEffect(
        () => {
            useAsyncStorage.getItem('auth_token')
            .then((token) => {
                if(token){
                    setLoggedIn(true)
                }
            })
        } , []
    )

    const SignOut = ()=>{
        useAsyncStorage.removeItem('auth_token')
        .then(()=>{
            setLoggedIn(false)
        })
    }

    return(
        <View>
            <DrawerHeader username = 'Danish hello' /> // Custom drawer header
            <View style={styles.DrawerBody}>
                <CustomDrawerLink name="Home" iconName='home' navigationScreen='HomeScreen' navigation={navigation} />
                {
                    logged_in ?
                    <View>
                        <CustomDrawerLink name="Profile" iconName='user'  /> // Drawer custom buttons
                        <CustomDrawerLink name="Cart" iconName='hamburger'  />
                    </View>
                    : undefined
                }
                <Divider/>
                {
                    logged_in ?
                    <TouchableOpacity style={{flexDirection:'row' , alignItems:'center'}} onPress={()=>{SignOut()}} >
                        <FontAwesome5 name='sign-out-alt' style={{fontSize:20, marginRight:10 , color:COLORS.red_color, width:35}} />
                        <Text style={{fontSize:16 , color:'gray'}}>Sign Out</Text>
                    </TouchableOpacity>
                    :
                    <View>
                        <CustomDrawerLink name="Sign In" iconName='sign-in-alt'  navigationScreen='LoginScreen' navigation={navigation} />
                        <CustomDrawerLink name="Create New Account" iconName='user-plus'  navigationScreen='RegisterScreen' navigation={navigation} />
                    </View>
                }

            </View>
        </View>
    )
}

Edited part ADDED PARENT COMPONENT Here it is

As you mentioned i am using useEffect Hook in my parent component, Here is the code

here i am making Drawer (Side navigation bar)

const Drawer = createDrawerNavigator()

Here is App component

const App = () =>{
  const network = useNetInfo()

  const [Scren_navigation , setNavigation] = useState('')
  const [activeDrawer , setActiveDrawer] = useState(<EmptyDrawer/>)

  const UpdateScreen = (props) =>{
    setNavigation(props.navigation)
    return activeDrawer
  }

  useEffect(()=>{
      setTimeout(() => {
          network.isInternetReachable ?  setActiveDrawer(<CustomDrawer  navigation={Scren_navigation} />)  : setActiveDrawer(<NoInternetDrawer navigation={Scren_navigation} />)
      }, 5000);
  })


  return(
    <NavigationContainer>
      <Drawer.Navigator drawerContent={({navigation}) => <UpdateScreen navigation={navigation} /> } >
        <Drawer.Screen name="StackNavigation"  component={Navigation} />
      </Drawer.Navigator>
      
    </NavigationContainer>
  )
}

I have added parent Component, Please let me know where i was doing wrong things

Upvotes: 1

Views: 183

Answers (1)

MaartenDev
MaartenDev

Reputation: 5811

The package provides two API's one with AsyncStorage and the other one is useAsyncStorage. Both have different usage patterns, you have mixed both in your snippet. Checkout the code below for example usage of each API.

AsyncStorage

const CustomDrawer =({navigation})=>{
    const [logged_in , setLoggedIn]= useState(false)

    useEffect(
        () => {
            AsyncStorage.getItem('auth_token')
            .then((token) => {
                if(token){
                    setLoggedIn(true)
                }
            })
        } , []
    )

    const SignOut = ()=>{
        AsyncStorage.removeItem('auth_token')
        .then(()=>{
            setLoggedIn(false)
        })
    }

    return ...;
}

UseAsyncStorage

const CustomDrawer =({navigation})=>{
    const [logged_in , setLoggedIn]= useState(false);
    const { getItem, setItem, removeItem } = useAsyncStorage('@storage_key');


    useEffect(
        () => {
           getItem('auth_token')
            .then((token) => {
                if(token){
                    setLoggedIn(true)
                }
            })
        } , []
    )

    const SignOut = ()=>{
       removeItem('auth_token')
        .then(()=>{
            setLoggedIn(false)
        })
    }

    return ...
}

The second problem is caused by the parent component because of a missing [] argument to the useEffect:

const App = () => {
    const network = useNetInfo()

    const [isRunningAvailabilityCheck, setIsRunningAvailabilityCheck] = useState(true);
    const [internetIsAvailable, setInternetIsAvailable] = useState(true);

    useEffect(() => {
        setTimeout(() => {
            setInternetIsAvailable(network.isInternetReachable);
            setIsRunningAvailabilityCheck(false);
        }, 5000);
    }, []);

    return (
        <NavigationContainer>
            <Drawer.Navigator drawerContent={({navigation}) => {
                if(isRunningAvailabilityCheck){
                    return <EmptyDrawer/>;
                }
                
                if(internetIsAvailable){
                    return <CustomDrawer  navigation={navigation} />
                }
                return <NoInternetDrawer navigation={navigation} />
            }}>
                <Drawer.Screen name="StackNavigation" component={Navigation}/>
            </Drawer.Navigator>

        </NavigationContainer>
    )
}

Async storage Docs

Upvotes: 1

Related Questions