React Native cannot update State Hook with data from AsyncStorage

Viewed 782

Hello im currently learning AsyncStorage in react native. so i write some state like this

const [isLoading,setIsLoading] = useState(true)
const [id, setId] = useState(null)

i set it null because i want to get the id from AsyncStorage, so i write a simple function to get and set the value like this :

async function getAsyncStorageId(){
  const userId = await AsyncStorage.getItem('id')
  console.log('user id from AsyncStorage is: ',userId)
  setId(userId)
  console.log('state hooks id : ',id)
}

and i put it into useEffect Hooks

 useEffect(()=>{
  getAsyncStorageId()
 },[])

so i test my code the id state wont update it stay null, but the console.log(userId) have an id value.

user id from AsyncStorage is:  6
state hooks id :  null

i dont know why i cant set the state with value from the asyncstorage

======================= *edit : this is the code that i used to set the id in AsyncStorage. i put this code in my Login Screen, so when the user succesfully login i store the id, username, token, and role in async storage

const login = async () => {
try {
  let response = await axios.post(`${url}/users/login`, {
    email: props.email,
    password: props.password,
  });
  let loginData = response.data;
  console.log(loginData,'sukses login')
  setAsyncStorage('token',loginData.token)
  loginData.name === null ? setAsyncStorage('name', 'pengguna') : setAsyncStorage('name',loginData.name)
  setAsyncStorage('role', loginData.role)
  setAsyncStorage('id', loginData.id)

  props.navigation.navigate("Artikel",{
    id:loginData.id,
    token:loginData.token,
    name:loginData.name
  })

} catch (error) {
  console.log('error login',props.email,props.password);
  alert(error.response.data.message)
}

};

export const setAsyncStorage = async (key, value) => {
  try {
    await AsyncStorage.setItem(`${key}`, `${value}`);
  } catch (error) {
    console.log(error);
  }
};

=============== update 2=========================

so i've tried change id value in login function into string like this

const login = async () => {
try {
  let response = await axios.post(`${url}/users/login`, {
    email: props.email,
    password: props.password,
  });
  let loginData = response.data;
  console.log(loginData,'sukses login')
  setAsyncStorage('token',loginData.token)
  loginData.name === null ? setAsyncStorage('name', 'pengguna') : setAsyncStorage('name',loginData.name)
  setAsyncStorage('role', loginData.role)
  setAsyncStorage('id', loginData.id.toString())

  props.navigation.navigate("Artikel",{
    id:loginData.id,
    token:loginData.token,
    name:loginData.name
  })

} catch (error) {
  console.log('error login',props.email,props.password);
  alert(error.response.data.message)
}

};

============================ and here is the full code in my profile screen page, so i've tried using setTimeout to console.log(id) and run function to get user id, but still no luck

import React, { useState, useEffect } from 'react'
import { KeyboardAvoidingView, Text, View, AsyncStorage } from 'react-native'

import ProfileForms from './ProfileForms/ProfileForms'
import axios from 'axios'
import styles from "../styles";
import {url} from '../config/variables'
import { ScrollView } from 'react-native-gesture-handler';

export default function ProfileScreen (){
  const [isLoading,setIsLoading] = useState(true)
  const [id, setId] = useState(null)
  const [name, setName] = useState(null)
 
  async function getAsyncStorageId(){
    const userId = await AsyncStorage.getItem('id')
    console.log('user id from AsyncStorage is: ',userId)
    await setId(userId)
    console.log('state hooks id : ',id)
  }

  async function getUserData(){
    console.log('getting userr data')
    try {
      let result = await axios.get(`${url}/users/${id}`)
      console.log(result.data)
      setName(result.data.name)
      setIsLoading(false)
    } catch (error) {
      console.log(error)
    }
  }

  function test(){
    getAsyncStorageId()
    setTimeout(() => {
      console.log(id)
      getUserData()
    }, 5000);
  }

  useEffect(()=>{
    test()
  },[])

  return( 
    <ScrollView>
    <KeyboardAvoidingView behavior={Platform.OS == "ios"? "padding" : "height"} style={styles.container}>
      {
        !isLoading &&
        <ProfileForms
          id={id}
          name={name}
          setName={setName}
        />
      }
      {
        isLoading &&
        <View>
          <Text>Loading</Text>
        </View>
      }
    </KeyboardAvoidingView>
    </ScrollView>
  )
}

=============== update again =================

so i created a variable and i replace my id state with this variable and it works.. for the moment i think im gonna stick with this

let desperateId = null



async function getAsyncStorageId(){
  const userId = await AsyncStorage.getItem('id')
  console.log('user id from AsyncStorage is: ',userId)
  desperateId=userId
  await setId(userId)
  console.log('state hooks id : ',id)
}
1 Answers

I think you can only store the string type in AsyncStorage. Try setting the value like this.

AsyncStorage.setItem('id', '5')

In your case, it would be like this

setAsyncStorage('id', JSON.stringify(loginData.id))

Update:

const [id, setId] = useState('')
Related