Search code examples
react-nativeexpoasyncstorage

Persisting data between app launches with Expo & React Native


Here's my App.js, everything else is as standard/simple as I can get it.

import React from 'react';
import { AsyncStorage, Text, View } from 'react-native';

export default class App extends React.Component {
  render() {

    console.log("Fetching data")
    AsyncStorage.getItem('@MySuperStore:key', (value) => {
      console.log("Fetched data: ", value)
      if(value == null) {
        console.log("Writing data!")
        AsyncStorage.setItem('@MySuperStore:key', 'data', () => {
          console.log("Wrote data!")
        })
      }
    })

    return(
    <View>
      <Text>Hello, ReplIt</Text>
    </View>
    );
  }
}

The fetched value is always null.

I've tried this both locally and on ReplIt. In all cases, the data does not persist across app loads; I always see:

Fetching data
Fetched data:  null
Writing data!
Wrote data!

What am I doing wrong? Do I have an incorrect assumption about how Expo interacts with the persistent storage? AFAIK, AsyncStorage is supposed to save stuff to the device; so I can close and re-open the app and have the data persist.


Solution

  • UPD: i just realized your code worked as expected... probably it is replit issue as mentioned in comment.

    Avoid any requests and async calls in render method, because it could be called may times depending on how props or state changing. Better put all related code into componentDidMount as it is recommended in documentation. It will be called only once when component mounted.

    Not sure why your code dodnt worked for you, callbacks are allowed for AsyncStorage, however wait works just fine for me:

    import React from "react";
    import { AsyncStorage, Text, View } from "react-native";
    
    export default class App extends React.Component {
      constructor() {
        super();
        this.state = {
          storedValue: null
        };
      }
      async componentDidMount() {
        let storedValue = await AsyncStorage.getItem("@MySuperStore:key");
        console.log("Fetched data: ", storedValue);
        if (storedValue == null) {
          console.log("Writing data!");
          storedValue = await AsyncStorage.setItem("@MySuperStore:key", "data");
        }
        this.setState({
          storedValue
        });
      }
    
      render() {
        const { storedValue } = this.state;
        return (
          <View>
            <Text>Hello, ReplIt</Text>
            <Text>This is Stored Value, '{storedValue}'</Text>
          </View>
        );
      }
    }