I'm using useContext & useReducer from Hooks & AsyncStorage.setItem in useEffect to save the data whenever state gets updated. On app reload I want to make sure to get saved data using AsyncStorage.getItem and add it to the initial state.
I tried to add init function with async as the third property to useReducer but still, it's not replacing initial data with received data. Please go through below code and help.
Thank you in advance!
Current code where I can save data to AsyncStorage
const [user, dispatch] = useReducer(userReducer, {});
useEffect(() => {
AsyncStorage.setItem('user', JSON.stringify(user))
}, [user]);
return(
<UserContext.Provider value={{user,dispatch}}>
{props.children}
</UserContext.Provider>
);
}
Below is the code I tried, but unable save existing data as initial data.
const getUser = async function() {
const userData = await AsyncStorage.getItem('user')
console.log("parse");
console.log(userData);
console.log("parsed data");
console.log(JSON.parse(userData));
return userData ? JSON.parse(userData) : {};
}
export const UserContext = createContext();
const UserContextProvider = (props) => {
const [user, dispatch] = useReducer(userReducer, {}, getUser);
useEffect(() => {
console.log("context");
console.log(JSON.stringify(user));
AsyncStorage.setItem('user', JSON.stringify(user))
}, [user]);
return(
<UserContext.Provider value={{user,dispatch}}>
{props.children}
</UserContext.Provider>
);
}
Thank you! Updated and working code based on below suggestion and with minor changes.
const getUser = async () => {
try {
const user = await AsyncStorage.getItem('user')
return user ? JSON.parse(user) : {};
} catch (e) {
console.log('Failed to fetch the data from storage');
}
}
export const UserContext = createContext();
const UserContextProvider = (props) => {
const [user, dispatch] = useReducer(userReducer, {});
// Loading initial Satte
useEffect(() => {
async function fetchUser() {
const user = await getUser();
dispatch({type: 'ADD_USER', user});
}
fetchUser();
}, []);
// Update AsyncStorage when user is updated
useEffect(() => {
// This check is required to avoid initial writing to asyncStorage
if(user) {
AsyncStorage.setItem('user', JSON.stringify(user))
}
}, [user]);
return(
<UserContext.Provider value={{user,dispatch}}>
{props.children}
</UserContext.Provider>
);
}