Search code examples
javascriptreact-nativeasynchronouspromiserect

Resolving promise issue with react native and Async Storage


I have spent days now and have read numerous articles and answers here and I can not wrap my head around this. Below is just my last attempt at this.

I just need to use data stored in Async Storage and use it inside App()

Can someone please take a look at this simple App() starting code and explain in the planest possible way how to resolve the promise here.

import { StatusBar } from 'expo-status-bar'
import React, { useState, useEffect } from 'react'
import { StyleSheet, Text, View } from 'react-native'
import { Button, Input } from 'react-native-elements'
import Icon from 'react-native-vector-icons/FontAwesome'
import AsyncStorage from '@react-native-async-storage/async-storage'

export default async function App () {
  let [userData, setUserData] = useState({})

  useEffect(() => {
    storeData('test2')
    getItem()
  }, [])

  const storeData = async value => {
    try {
      await AsyncStorage.setItem('@storage_Key', value)
    } catch (e) {
      // saving error
    }
  }

  const getItem = async () => {
    const value = await AsyncStorage.getItem('@storage_Key')
    return value
  }

  userData = getItem()
  console.log(userData)

  return (
    <View style={styles.container}>
      <Text>Local storing: {userData}</Text>
      <StatusBar style='auto' />
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center'
  }
})

The <Text>Local storing: {userData}</Text> is allways a unresolved proise object.

I had some success with previous code where console.log(userData) did actually produce the wanted value but it is still not useable inside <Text>. I just dont get it.

Thank you in advance and please keep in mind I'm new to react native.

EDIT: latest attemt:

import { StatusBar } from 'expo-status-bar'
import React, { useState, useEffect } from 'react'
import { StyleSheet, Text, View } from 'react-native'
import { Button, Input } from 'react-native-elements'
import Icon from 'react-native-vector-icons/FontAwesome'
import AsyncStorage from '@react-native-async-storage/async-storage'

export default async function App () {
  let [userData, setUserData] = useState({})

  const storeData = async value => {
    try {
      await AsyncStorage.setItem('@storage_Key', value)
    } catch (e) {
      // saving error
    }
  }

  storeData('test2')


  const getData = async () => {
    try {
      const value = await AsyncStorage.getItem('@storage_Key')
      if(value !== null) {
        console.log(value)
        return value
      }
    } catch(e) {
      // error reading value
    }
  }
  

  userData = await getData()
  console.log(userData)

  return (
    <View style={styles.container}>
      <Text>Local storing: {userData}</Text>
      <StatusBar style='auto' />
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center'
  }
})

Now I get for some reason 4 test2 , correct values consoled logged but still get an error:

Error: Objects are not valid as a React child (found: object with keys {_U, _V, _W, _X}). If you meant to render a collection of children, use an array instead.

which is a promise object, and app fails to build.


Solution

  • Fixed it:

    import { StatusBar } from 'expo-status-bar'
    import React, { useState, useEffect } from 'react'
    import { StyleSheet, Text, View } from 'react-native'
    import { Button, Input } from 'react-native-elements'
    import Icon from 'react-native-vector-icons/FontAwesome'
    import AsyncStorage from '@react-native-async-storage/async-storage'
    
    const storeData = async value => {
      try {
        await AsyncStorage.setItem('@storage_Key', value)
      } catch (e) {
        // saving error
      }
    }
    
    storeData('test2')
    
    
    
    export default function App () {
      let [userData, setUserData] = useState('')
    
      useEffect(() => {
        getData()
      }, [])
    
      const getData = async () => {
        try {
          const value = await AsyncStorage.getItem('@storage_Key')
          if (value !== null) {
            console.log(value)
            setUserData(value)
            userData = value
          }
        } catch (e) {
          // error reading value
        }
      }
    
    
      console.log(userData)
    
      return (
        <View style={styles.container}>
          <Text>Local storing: {userData}</Text>
          <StatusBar style='auto' />
        </View>
      )
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#fff',
        alignItems: 'center',
        justifyContent: 'center'
      }
    })
    
    • there shouldn't have been async in export default function App () {

    • getData() get data should have been iniciated inside useEffect

      useEffect(() => { storeData('test2') getData() }, [])

    • I have also set the state inside getData()

      userData = value