Search code examples
javascriptfunctionreact-nativeasynchronousrendering

Render child using async in function React-Native


I saw many answers like that one, but no one worked for me so far. I want to get data from AsyncStorage and render a page if there is login data, but if there isn't login data I want to render another page.

But I am having trouble while developing this...

I tried this:

export default class Routes extends React.Component {
  RetrieveData = async () => {
    try {
      const value = await AsyncStorage.getItem('login');
      if (value !== null) {
        // We have data!!
        return (
            <View>Test</View>
        );
      }
    } catch (error) {
      // Error retrieving data
    }
  };

  render() {
    return (
      {RetrieveData}
    )
  }
}

I also tried using a componentDidMount technique... but didn't work...

My current code that still doesn't work:

export default function Routes() { 
  function CheckLogged(){
    var login;

    async function checkLogin(){
      await AsyncStorage.getItem('login', (err, result) => {
        login = JSON.parse(result);
      });
    }
  
    checkLogin();


    if (login != null){
      return(
        <Stack.Navigator>
          <Stack.Screen name="Login" component={Login} />
        </Stack.Navigator>
      )
    }
      
    else{
      return(
        <Stack.Navigator>
          <Stack.Screen name="Home" component={Home} />
        </Stack.Navigator>
      )
    }
  }


  return(
    <NavigationContainer>
      <CheckLogged/>
    </NavigationContainer>
  )
}

Solution

  • You are using react and setting variables like that wont cause rendering the best approach to take would be to use states and make use of the useeffect hook to retrieve your data from asyn storage.

    Here two state variables are used, one to show the loading indicator till the read is done and the other one to hold the logindata if available. The use effect will run when the component is mounted. And the screens in the stack are conditionally rendered.

    function Routes() {
      const [isLoggedIn, setIsLoggedIn] = React.useState(false);
      const [isLoaded, setIsLoaded] = React.useState(true);
    
      useEffect(() => {
        AsyncStorage.getItem('login').then((result) => {
          setIsLoaded(JSON.parse(result));
        });
      }, []);
    
      if (isLoaded) return <ActivityIndicator />;
    
      return (
        <NavigationContainer>
          <Stack.Navigator>
            {isLoggedIn ? (
              <Stack.Screen name="Home" component={Home} />
            ) : (
              <Stack.Screen name="Login" component={Login} />
            )}
          </Stack.Navigator>
        </NavigationContainer>
      );
    }