Home > database >  Async function in UseEffect
Async function in UseEffect

Time:09-21

I am trying to get data from AsyncStorage and eventually map this data to a list of buttons on my home screen. The data is saved to AsyncStorage from an API call that is made upon login.

In my async function, I am able to successfully retreive the data from AsyncStorage and parse it into JSON format, and then log it to the console. It looks like this:

{
    1 : {title:"Timesheet",component_name:"Timesheet"}
    2 : {title:"Personal Info",component_name:"PersonalInfo"}
    3 : {title:"Employee Directory",component_name:"EmployeeListing"}
}

The problem I am running into is that I can't save this data to my useState variable and then render it into the component after useState is updated by my async function. Every time I try to access this data, I either get null or a Promise object. How can I access the data after useState is updated? Do I need to use a different React hook to call the Async function?

Here is the code that I am using:

import { Text, View, StyleSheet } from 'react-native';
import { useState, useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';


export default function HomeScreen() {

const [buttonData, setButtonData] = useState(null);

useEffect (() => {
  const loadHomeScreenButtons = async () => {
    try {
      const buttons = await AsyncStorage.getItem('app_screens').then(screens => {
        // Parse the JSON data from its stored string format into an object.
        let app_screens_json = JSON.parse(screens);
        let app_screens_list = app_screens_json.app_screens;
        console.log(app_screens_list);  // This outputs the data to the console.
        setButtonData(app_screens_list);  // Trying to set the button data in useState.
        return app_screens_list;
      });
    }
    catch (e) {
      console.log(e)
    }
  }

  loadHomeScreenButtons();

}, [])

return (
  <View style={home_styles.container}>
    <Text>{buttonData[1]["title"]}</Text>
  </View>
);

}

CodePudding user response:

You just need to render a loading component until your data is fetched.

{ buttonData?.length? 
   <Text>{buttonData[1]["title"]}</Text> : <Text>...loading</Text>
}

You are getting an error as you are trying to access a property that does not exist at the render.

CodePudding user response:

Try this way

const loadHomeScreenButtons = useCallback(async () => {
  try {
      const screens = await AsyncStorage.getItem('app_screens')
      const app_screens_json = JSON.parse(screens)
      setButtonData(app_screens_json.app_screens)
    }
    catch (e) {
      console.log(e)
    }
}, []);

 useEffect(() => {
    loadHomeScreenButtons();
 }, [loadHomeScreenButtons]);

  • Related