Search code examples
react-nativeasyncstorage

Async storage doesnt display when i reload


I am VERY VERY new to React Native. i have never posted on a forum, sorry if formatting is incorrect. Please bear with me. When i store a value using Async, i write to the console, so i know it is storing the value, then i read back the value and i know it is there when i read from the console but it wont set my radio button to the value stored using Async. The first line of these 4 does NOT work even though i KNOW the data is set but the 3 commented out lines each work fine if i test them separately but it is the first line i want to work:

  const [checked, setChecked] = useState(getData());
 // const [checked, setChecked] = useState('first');
  //const [checked, setChecked] = useState('second');  
  //const [checked, setChecked] = useState(params.startvalue); 

Here is full code:

import React, { useState , useEffect} from 'react';
import { Text, View, StyleSheet, Button } from 'react-native';
import Constants from 'expo-constants';
import AsyncStorage from '@react-native-async-storage/async-storage';

// or any pure javascript modules available in npm
import { RadioButton } from 'react-native-paper';


const storeData = async (value) => {
  try {
    console.log("in storeData value is-->" + value.toString());
    await AsyncStorage.setItem('@storage_Key', value.toString())
  } catch (e) {
    console.log("didntwork in StoreData");
  }
}

const getData = async () => {
  try {
    const value = await AsyncStorage.getItem('@storage_Key');
    console.log("value in getData is:", value.toString());
    return value != null ? value.toString() : null;
  } catch (e) {
    console.log("error in getData", { e });
  }
}

const MyRadioButton = params => {
  
  const [checked, setChecked] = useState(getData());
 // const [checked, setChecked] = useState('first');
  //const [checked, setChecked] = useState('second');  
  //const [checked, setChecked] = useState(params.startvalue);  
  
   return (
    <View>
      <Text>{params.startvalue}</Text>
      <Text>{params.message1}
        <RadioButton
          value="first"
          status={checked == 'first' ? 'checked' : 'unchecked'}
          onPress={() => {
            setChecked('first');
            params.setxDisabled(true);
            storeData('first');
          }
          }
        /></Text>
      <Text>{params.message2}
        <RadioButton
          value="second"
          status={checked == 'second' ? 'checked' : 'unchecked'}
          onPress={() => {
            setChecked('second');
            params.setxDisabled(false);
            storeData('second');
          }
          }
        /></Text>
    </View>
  );
};


export default function App() {
  const [xdisabled, setxDisabled] = useState(true);
  return (
    <View style={styles.container}>
        <Text style={styles.auto} >Welcome </Text>
        <Text style={styles.auto} >Blah Blahhhh</Text>
        <MyRadioButton message1="I do NOT agree to the terms" message2="I agree to the terms" setxDisabled={setxDisabled} startvalue="first" />
        <Button title="continue" disabled={xdisabled} onPress={() => navigation.navigate('Home')} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  paragraph: {
    margin: 24,
    fontSize: 18,
    fontWeight: 'bold',
    textAlign: 'center',
  },
});

Solution

  • Okay so if I understand you correctly you want to load the current state from AsyncStorage. You are never actually getting the value from AsyncStorage on loading the page because it is an async function. You need to await the return value.

    I recommend using useEffect() for this task to immitate a component mount. You should import it from from react.

    Try something like this:

    const [checked, setChecked] = useState('default value');
    
    useEffect(() => {
       const asyncWrap = async () => {
          const value = await getData();
          setChecked(value);
       }
       asyncWrap() // you can't make async calls directly in useEffect
    }, []); // <-- empty [] is very important!
    
    

    You can now use the state as usual.