Search code examples
react-nativereact-hooksasyncstorage

why is my async storage returning previously stored value?


So, I was working on authentication and I wanted to store values (object) in that storage. But I tried a sample first. The problem with the code is that it is returning previously stored value. I don't know if the problem is with the useState. But I did make sure that was not the issue.

function App() {
const [user, setUser] = useState();
  const storeData = async () => {
    const value={
    "name":"jameel",
    "email":"caseyvlogger2311",
    "age":"23",
  }
    try {
      const jsonValue = JSON.stringify(value)
      await AsyncStorage.setItem('@profile', jsonValue)
      console.log("saved")
      console.log('console after saving (original value): ' + value.name)
    } catch (e) {
      // saving error
    }
  }
  const getData = async () => {
    console.log('console in getData (user useState name): ' + user.name)
    try {
      const jsonValue = await AsyncStorage.getItem('@profile')
      jsonValue != null ? setUser(JSON.parse(jsonValue)) : null;
      console.log("console useState value after getting data: " + user.name)
    } catch(e) {
      // error reading value
    }
  }
  return (
    <Button onPress={storeData}>Save data</Button>
    <Button onPress={getData}>Get data</Button>
  )
}

Output when I save and then get the value immediately: Screenshot

Please let me know if there is something missing.


Solution

  • Because setUser is asynchronous as well.

    Thus when you do

    jsonValue != null ? setUser(JSON.parse(jsonValue)) : null;
    console.log("console useState value after getting data: " + user.name)
    

    you are triggering a state change, but this hasn't been executed yet when you access user.name, thus user still has the same value as in the current state. If you do

    console.log(jsonValue)
    

    you probably will see the "correct" value read from the storage ...

    And just as a sidenote: Misusing the ternary operator ? : as sort of an if in a statement is considered bad style. It's harder to read and may lead to errors on refactoring. Why not just just do

    if (jsonValue != null) {
      setUser(JSON.parse(jsonValue));
    }
    

    instead? Is much easier to read and the intentions of that code perfectly clear ...