Search code examples
reactjssavenativeasyncstorage

AsyncStorage doesn't save data but no error


Now I am aware that there are many of questions that asked the same thing. But I also found many that implemented the right methods but nothing worked for them even peoples' answers

Basically, I wanted to use AsyncStorage to save a few user preferences. At first everything worked and was saved correctly, but then suddenly nothing worked anymore.

I kept trying and trying, and made a very interesting finding.

First here's my code:

My import:

import AsyncStorage from '@react-native-async-storage/async-storage';

Default State:

  state : AppState = {
    messages: [],
    isMuted: false
  }

This is my getter. It works on init:

componentDidMount() {
      this.getSettings();
  }

  async getSettings() {
    try {
      AsyncStorage.getItem("muted").then((muted)=> {
        if (muted != null) {
          this.setState({"isMuted": eval(muted)});
          console.log("init! "+this.state.isMuted.toString());
        } else {
          console.log("init! found null");
        }
      })

    } catch(e) {
      // error reading value
    }
  }

Here's my setter, it works onPress of a button

 onPressSpeaker = async () => {
    var muted = !this.state.isMuted;
    this.setState({"isMuted": muted});

    try {
      await AsyncStorage.setItem("muted", this.state.isMuted.toString());
      console.log("saved! "+this.state.isMuted.toString());

      const muted = await AsyncStorage.getItem('muted');
      if(muted !== null) {
        console.log("data found! "+this.state.isMuted.toString());
      }

    } catch (e) {
      console.log("error")
    }
  };

I believe I set everything correctly.

But here's my log (from Flipper)

20:57:41.654
init! true

20:57:44.247
saved! false

20:57:44.256
data found! false

20:58:04.788
Running "Voice Message" with {"rootTag":51}

20:58:05.800
init! true

The last init was supposed to return the new value but it keeps returning the old value again and again, everytime I refresh (restart) the application.

Did I do something wrong? Am I missing something? Is there something I need to know about react-native-async-storage?


Solution

  • I think the problem that you are storing the this.state.isMuted value before the state mutates

    To better understand you can try this code

     onPressSpeaker = async () => {
       var muted = !this.state.isMuted;
       this.setState({"isMuted": muted});
            
       try {
         //Here we are trying to log the state before Add it to Storage
         console.log('State => Before AsyncStorage.setItem', this.state.isMuted)
    
         await AsyncStorage.setItem("muted", this.state.isMuted.toString());
    
         console.log("saved! "+this.state.isMuted.toString());
            
         const muted = await AsyncStorage.getItem('muted');
    
           if(muted !== null) {
             console.log("data found! "+this.state.isMuted.toString());
           }
            
         } catch (e) {
                  console.log("error")
           }
     };
    

    Your log will now be like this

    20:57:41.654
    init! true
    
    20:57:44.247
    'State => Before AsyncStorage.setItem' true
    
    20:57:44.247
    saved! false
    
    20:57:44.256
    data found! false
    

    Solution: So you need to write the function in the callback to the setState function

     storeIsMuted = async () => {
        try {
          console.log("before setItem", this.state.isMuted.toString());
          await AsyncStorage.setItem("muted", this.state.isMuted.toString());
          console.log("saved! " + this.state.isMuted.toString());
          //
          const muted = await AsyncStorage.getItem("muted");
          if (muted !== null) {
            console.log("data found! " + this.state.isMuted.toString());
          }
        } catch (e) {
          console.log("error");
        }
      };
      onPressSpeaker = () => {
        var muted = !this.state.isMuted
        this.setState({ isMuted: muted }, async () => this.storeMuted());
      };
    

    Documentation SetState