I'm trying to understand how AsyncStorage works Consider a screen to configure default language:
// Selected radio button value
const [value, setValue] = React.useState('first');
// Default lang
const [defaultLang, setDefaultLang] = useState('');
const handleButtonClick = () => {
if (value === 'first'){
Toast.show({
type: 'error',
text1: 'Please pick a language!',
});
} else {
console.log("Saved language: "+value);
setAppDefaultLanguage();
}
};
async function setAppDefaultLang() {
return AsyncStorage.setItem('APP_DEFAULT_LANG',value);
};
async function getAppDefaultLang(){
const lang = await AsyncStorage.getItem('APP_DEFAULT_LANG') as string;
setDefaultLang(lang);
return lang;
}
useEffect(() => {
// Print saved default lang
const appLang = getAppDefaultLang();
console.log("dbg: "+JSON.stringify(appLang));
console.log("Default lang: "+appLang);
});
Say the value is lang_en. After handleButtonClick is invoked, this line will be printed on log:
Saved language: lang_en
OK so far so good. Now dismiss the screen, and re-open the change language screen. On log, I see this:
dbg: {"_h":0,"_i":0,"_j":null,"_k":null}
Default lang: [object Object]
Why is that garbage value printed, instead of lang_en?
The value you are seeing {"_h":0,"_i":0,"_j":null,"_k":null} is a pending, unresolved promise.
I am assuming that getAppLang invokes AsyncStorage.getItem, so in order to see the actual value, but you have it inside a useEffect hook so your syntax is incorrect const appLang = getAppLang(); you need to await the promise to get resolved.
You can solve it by calling await getAppDefaultLang() inside an async function in the hook.
Something like this:
useEffect(() => {
const getLanguage = async () => {
const appLang = await getAppDefaultLang();
console.log("dbg: "+JSON.stringify(appLang));
console.log("Default lang: "+appLang);
}
getLanguage();
},[]); // ADDING THE DEPENDENCY ARRAY HERE FOR THE USEEFFECT TO RUN ONLY ONCE
Note: I added an empty array as a hook dependency [] so that it doesn't keep re-triggering the hook on render.