简体   繁体   中英

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>
  )
}

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>
  );
}

It is recommended that you use react-native-easy-app , through which you can access AsyncStorage synchronously, and can also store and retrieve objects, strings or Boolean data

  import { XStorage } from 'react-native-easy-app';
  import { AsyncStorage } from 'react-native';
  // or import AsyncStorage from '@react-native-community/async-storage';

   export const RNStorage = {
       token: undefined, 
       isShow: undefined, 
       userInfo: undefined
   };
   
  const initCallback = () => {

       // From now on, you can write or read the variables in RNStorage synchronously
       
       // equal to [console.log(await AsyncStorage.getItem('isShow'))]
       console.log(RNStorage.isShow); 
       
       // equal to [ await AsyncStorage.setItem('token',TOKEN1343DN23IDD3PJ2DBF3==') ]
       RNStorage.token = 'TOKEN1343DN23IDD3PJ2DBF3=='; 
       
       // equal to [ await AsyncStorage.setItem('userInfo',JSON.stringify({ name:'rufeng', age:30})) ]
       RNStorage.userInfo = {name: 'rufeng', age: 30}; 
  };
  
  XStorage.initStorage(RNStorage, AsyncStorage, initCallback); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM