I have the following React Native modules:
_localStorage.js
import AsyncStorage from '@react-native-community/async-storage';
const _storeData = async (key, value) => {
try {
await AsyncStorage.setItem(key, value);
} catch (error) {
console.log(error);
}
}
const _retrieveData = async (key) => {
try {
await AsyncStorage.getItem(key);
} catch (error) {
console.log(error);
}
}
export {_storeData, _retrieveData};
AppHeader.js
import React from 'react';
import {Button} from 'react-native-paper';
import {_retrieveData, _storeData} from '../../utils/_localStorage'
const LoginButton = () => {
return (
<Button icon='login' color='yellow' onPress={() => navigation.navigate('Login')}>
Login
</Button>
)
}
const UserButton = (user) => {
return (
<Button color='yellow' onPress={() => console.log('Botón usuario presionado...')}>
text
</Button>
)
}
const AppHeader = ({navigation, route}) => {
const user = _retrieveData('user');
console.log(user);
return user === ''? <LoginButton />: <UserButton user={user} />;
}
export default AppHeader;
I expect _retrieveData()
to return the value of the key parameter, or null if it doesn't exits, but what I am getting in the console is this: {"_U": 0, "_V": 0, "_W": null, "_X": null}
.
This is not how documentation of AsyncStorage indicates it works.
It's because you're not waiting for _retrieveData
to finish. You're just setting user
to the async function instead of waiting for its returned value.
Try something like this:
const AppHeader = ({navigation, route}) => {
const [user, setUser] = useState();
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
fetchUser();
}, [])
const fetchUser = async () => {
setIsLoading(true);
const userData = await _retrieveData('user');
setUser(userData);
setIsLoading(false);
}
if (isLoading) return <LoadingIndicator />
if (!!user) return <UserButton user={user} />
return <LoginButton />;
}
I've called fetchUser
in the initial useEffect
that gets called when the AppHeader component is first loaded. It sets a loading boolean to true and then requests the user data. When the userData is returned it sets it in state and sets loading to false.
You don't need the loading bit but I included it otherwise your app would show the login button while it's fetching the data. You'll have to create the LoadingIndicator
component yourself.
_retrieveData is returning promise here. You need to await for that promise to resolve. Try writing it like this:
const _retrieveData = async (key) => {
try {
const data = await AsyncStorage.getItem(key);
return data;
} catch (error) {
console.log(error);
}
}
AppHeader.js
const AppHeader = ({navigation, route}) => {
_retrieveData('user').then((user)=>{
console.log(user);
return user === ''? <LoginButton />: <UserButton user={user} />;
});
}
Read this for more clarity : https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With