Khả Nam
Khả Nam

Reputation: 43

How to get AsyncStorage data without waiting in react native?

I have trouble trying to retrieve data from AsyncStorage, I can't directly assign a state like that, since it always returns undefined, how can I avoid that?

export default class ListTodo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: {},
    };
  }
  componentDidMount() {
    //promise 
    GetDataAsyncStorage('@TODOS').then((data) => {
      this.setState({
        data: data,
      });
    });
  }
  render() {
    const {data} = this.state;
    console.log(data); // undefined
    return (
      <>
        <Header />
        <View>
          <FlatList
            data={data}
            renderItem={({item}) => <TodoItemComponent data={item} />}
            keyExtractor={(item) => item.id}
          />
        </View>
      </>
    );
  }
}

Here is my function to get data from asynStorage

export const GetDataAsyncStorage = async (key) => {
  try {
    let data = await AsyncStorage.getItem(key);
    return {status: true, data: JSON.parse(data)};
  } catch (error) {
    return {status: false};
  }
};

Upvotes: 1

Views: 1519

Answers (2)

rufeng
rufeng

Reputation: 121

Because AsyncStorage itself is asynchronous read and write, waiting is almost necessary, of course, another way to achieve, for example, to create a memory object, bind the memory object and AsyncStorage, so that you can read AsyncStorage synchronously.

For example, using the following development library can assist you to easily achieve synchronous reading of AsyncStorage react-native-easy-app

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

Upvotes: 0

Ashwith Saldanha
Ashwith Saldanha

Reputation: 1738

Add a state variable isLoading and toggle it after the data is got from AsyncStorage

snack: https://snack.expo.io/@ashwith00/async

code:

export default class ListTodo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: {},
      isLoading: false,
    };
  }
  componentDidMount() {
    this.getData();
  }

  getData = () => {
    this.setState({
      isLoading: true,
    });
    //promise
    GetDataAsyncStorage('@TODOS').then((data) => {
      this.setState({
        data: data,
        isLoading: false,
      });
    });
  };
  render() {
    const { data, isLoading } = this.state;

    return (
      <View style={styles.container}>
        {isLoading ? (
          <ActivityIndicator />
        ) : data.data ? (
          <FlatList
            data={data}
            renderItem={({ item }) => <Text>{item}</Text>}
            keyExtractor={(item, i) => i.toString()}
          />
        ) : (
          <Text>No Data Available</Text>
        )}
      </View>
    );
  }
}

Upvotes: 1

Related Questions