Search code examples
react-nativeasyncstorage

Retrieve data from react native async storage and render it


I have theese questions:

_storeData = async () => {
  try {
    await AsyncStorage.setItem("@MySuperStore:key", "I like to save it.");
  } catch (error) {
    // Error saving data
  }
};

Do I need to call _storeData(); to save the data?

I don't know if I have the data stored or not because of the next problem.

I use this code to retrieve data from async storage:

_retrieveData = async () => {
  try {
    const value = await AsyncStorage.getItem("@MySuperStore:key");
    if (value !== null) {
      // We have data!!
      return value;
    }
  } catch (error) {}
};

How am I supposed to render the data? I use _retrieveData() in react-native Text element and system shows me this message:

Render error - objects are not valid as a react child (found: object with keys _x, _y, _z, _A. 
If you ment to render a collection of children, use an array instead.

Solution

  • Do I need to call _storeData(); to save the data? yes (or you could call AsyncStorage.setItem() directly, but that is what that function is for).

    In the following snippet, you can log the data if it is found, that way you separate the error from the rendering error you are getting, and you can actually see what your data looks like:

    _retrieveData = async () => {
      try {
        const value = await 
    AsyncStorage.getItem("@MySuperStore:key");
        if (value !== null) {
          console.log("We have data!!", value)
          return value;
        }
      } catch (error) {}
    };
    

    I believe that the rendering error you are getting usually results from trying to render an object, where it should be an array like @Michael Bahl is saying, or a String, you probably need to destructure the data with {}.

    UPDATE: I played around with it for a little bit and there were a couple of things that needed to be fixed. Most importantly, you shouldn't just call a function and render it's return value in React Native. You should use useState to manage it. And for example useEffect to update it. After playing around I got it to work as I think you expected, here is the code, let me know if you have any questions about it:

    import React, { useState, useEffect } from 'react';
    import { Text, View, StyleSheet } from 'react-native';
    import Constants from 'expo-constants';
    import AppLoading from "expo-app-loading";
    // You can import from local files
    import AssetExample from './components/AssetExample';
    
    // or any pure javascript modules available in npm
    import { Card } from 'react-native-paper';
    
    import AsyncStorage from '@react-native-async-storage/async-storage';
    _storeData = async () => {
      try {
        await AsyncStorage.setItem("@MySuperStore:key", "I like to save it.");
        console.log('data saved')
      } catch (error) {
        console.log('error1', error)
    
      }
    };
    
    _storeData();
    
    const image = { uri: "https://jurajbevilaqua.com/bg.png" };
    
    export default function App() {
      const [IsReady, SetIsReady] = useState(false);
      const [savedData, setSavedData] = useState('')
      useEffect(()=> {
        const _retrieveData = async () => {
        try {
          const value = await AsyncStorage.getItem("@MySuperStore:key");
          if (value !== null) {
            console.log("we have data:", value)
            setSavedData(value)
          }
        } catch (error) {
          console.log('error2', error)
        }
        }
        _retrieveData();
      },[])
     
    
      const LoadFonts = async () => {
        await useFonts();
      };
    
      if (!IsReady) {
        return (
          <AppLoading
            startAsync={LoadFonts}
            onFinish={() => SetIsReady(true)}
            onError={() => {}}
          />
        );
      }
      return (
        <View style={styles.container}>
    
              <Text>            
                {savedData}
              </Text>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container:{
        flex:1, 
        alignItems:"center",
        justifyContent:"center",
      },
    })