Search code examples
javascriptreactjsreact-nativeasyncstorage

Render component after getting value from AsyncStorage in React Native


My React Component stores user's settings in the AsyncStorage and get's them on load. The storing and getting data works well, but there is a problem that components renders before the values has been got from the async function. How this could be fixed? This is my code:

import React from 'react';
import { View } from 'react-native';
import AsyncStorage from '@react-native-community/async-storage';
import { Media } from '../constants';

class SettingsScreen extends React.Component {
  
  constructor(props) {
    super(props);
    const settings = ['appLanguage', 'colorTheme'];
    for(const i of settings) {
      this.getData(i).then(
        value => {
          if(value === null || value === undefined) {
            this.state[i] = Media.initalSettings[i];
          }
          else {
            this.state[i] = value;
          }
        }
      );
    }
  }

  async storeData(key, value) {
    try {
      if(key[0] != '@') {
        key = '@' + key;
      }
      await AsyncStorage.setItem(key, value);
    } 
    catch(e) {
      console.warn(e);
    }
  }

  async getData(key) {
    try {
      if(key[0] != '@') {
        key = '@' + key;
      }
      const value = await AsyncStorage.getItem(key);
      return value;
    } 
    catch(e) {
      console.warn(e);
    }
  }

  render() {

    const { appLanguage } = this.state;

    return (
      <>
        <View>
          {appLanguage}
        </View>
      </>
    )
  }
}

export default SettingsScreen;

Solution

  • It looks like you are trying to set the state directly in the constructor. Try this:

      constructor(props) {
        super(props);
        const settings = ['appLanguage', 'colorTheme'];
        for(const i of settings) {
          this.getData(i).then(
            value => {
              if(value === null || value === undefined) {
                this.state[i] = Media.initalSettings[i];
              }
              else {
                this.setState({key: value})
              }
            }
          );
        }
      }
    

    Here is some documentation: https://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-directly