How to load a useState with data from async-storage without null for react-native

60 Views Asked by At

I need to initialize my useState with the value from local storage. I can't get async-storage to stop making everything async. If i initialize with null or a random default then I get multiple re renders as the promises get fulfilled which causes other issues. I also tried useAsuncStorage which also only returns async functions. I have the same exact code written using cookies with react-cookie and useCookie and do not have any issues. Do you all have any suggestions?

import { useEffect, useState } from "react";
import AsyncStorage from "@react-native-async-storage/async-storage";

const usePostFilterOptions = () => {
    const getPostFilterType = async () => {
        const savedPostFilterType = await AsyncStorage.getItem('postFilterType') ?? 'trending';
        return savedPostFilterType;
    }

    const getPostModeType = async () => {
        const savedPostModeType = await AsyncStorage.getItem('postModeType') ?? 'home';
        return savedPostModeType;
    }

    const [postFilterType, setPostFilterType] = useState(getPostFilterType());
    const [postModeType, setPostModeType] = useState(getPostModeType());


    const updatePostFilterType = async (type) => {
        await AsyncStorage.setItem('postFilterType', type);
        setPostFilterType(type);
    }

    const updatePostModeType = async (type) => {
        await AsyncStorage.setItem('postModeType', type);
        setPostModeType(type);
    }

    return { postFilterType, updatePostFilterType, postModeType, updatePostModeType };
};

export default usePostFilterOptions;


1

There are 1 best solutions below

3
Leroy On BEST ANSWER

Fetching data from localstore is just async. You can not make this sync. But you can add additional state like a prop isLoading or something like that. You can stop rendering or show a loading icon or whatever you like.

const [postFilterType, setPostFilterType] = useState("trending");
const [postModeType, setPostModeType] = useState("home");
const [isLoading, setLoading] = useState(true);


AsyncStorage.getItem('postFilterType').then(r => setPostFilterType(r));
AsyncStorage.getItem('postModeType').then(r => setPostModeType(r));

// your updateMethods

return {
   isLoading, 
   postFilterType
   postModeType,
   updatePostFilterType,
   updatePostModeType 
}

In your component

const {isLoading} = usePostFilterOptions();

if (isLoading) {
   return <div>Loading...</div>;
   // or
   return;  // stop rendering the component, and wait until data is fetched.
}

// render component here