2
votes

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
Can you show me the code where you set id in AsyncStorage ? - Ajin Kabeer
setId is asynchronous so it's normal that id is logged null just after calling setId. just add await before setId(userId) and normally it should work - Mahdi N
@MahdiN i've tried that but the value still "null" - QrQr
@MahdiN but when i edit my code (anywhere), the apps automatically refresh and somehow the value changed, but when i rebuild and go to profilescreen directly it wont change - QrQr
I think that it's because of fast refresh, when you change your code the emulator is refreshed with new code. I'm sure that the problem is with asynchronous setId, try to console log id after calling getAsyncStorageId in useEffect and add await to getAsyncStorageId - Mahdi N

1 Answers

0
votes

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('')