0

I am currently developing a React Native app that needs to support an offline mode.

The problem is that when the App is closed and re-open without any Internet connection, none of the Context values are loaded, whether it is the user login, the permissions, etc.

The Context is defined in the following AppContext.tsx file:

interface AppContextValue {
  login: string;
  setLogin: (loggedIn: string) => void;
  hasInternetConnection: boolean;
  setInternetConnection: (hasConnection: boolean) => void;
  hasCameraPermissions: boolean;
  setCameraPermissions: (hasCameraPermissions: boolean) => void;
  hasLocationPermissions: boolean;
  setLocationPermissions: (hasLocationPermissions: boolean) => void;
  offlineData: any[];
  setOfflineData: (offlineData: any[]) => void;
}

const AppContext = createContext<AppContextValue>({
  login: '',
  setLogin: () => { },
  hasInternetConnection: false,
  setInternetConnection: () => { },
  hasCameraPermissions: false,
  setCameraPermissions: () => { },
  hasLocationPermissions: false,
  setLocationPermissions: () => { },
  offlineData: [],
  setOfflineData: () => { },
});

interface AppProviderProps {
  children: React.ReactNode;
}

export const AppProvider: React.FC<AppProviderProps> = ({ children }) => {
  const [login, setLogin] = useState('');
  const [hasInternetConnection, setInternetConnection] = useState(false);
  const [hasCameraPermissions, setCameraPermissions] = useState(false);
  const [hasLocationPermissions, setLocationPermissions] = useState(false);
  const [offlineData, setOfflineData] = useState<any[]>([]);

  useEffect(() => {
    const storeOfflineData = async () => {
      try {
        if (offlineData?.length)
          await AsyncStorage.setItem(offlineKey, JSON.stringify(offlineData));
      } catch (error) {
        console.error('Error storing offline data:', error);
      }
    };

    storeOfflineData();
  }, [offlineData]);

  useEffect(() => {
    const hasConnection = NetInfo.addEventListener((state) => {
      setInternetConnection(state.isConnected!);
    });
    const checkLogin = async () => {
      const userNumber = await getString(loginKey);
      if (userNumber)
          setLogin(userNumber);
    };
    const checkCameraPermission = async () => {
      const cameraPermission = await requestCameraPermission();
      setCameraPermissions(cameraPermission);
    };
    const checkLocationPermission = async () => {
      const locationPermission = await requestLocationPermission();
      setLocationPermissions(locationPermission);
    };
    const retrieveOfflineData = async () => {
      try {
        const storedData = await AsyncStorage.getItem(offlineKey);
        if (storedData && JSON.stringify(offlineData) !== storedData)
          setOfflineData(JSON.parse(storedData));
      } catch (error) {
        console.log('Error retrieving offline data:', error);
      }
    };

    // return () => {
      hasConnection();
      checkLogin();
      checkCameraPermission();
      checkLocationPermission();
      retrieveOfflineData();
    // };
  }, []);

  return (
    <AppContext.Provider
      value={{
        login,
        hasInternetConnection,
        setLogin,
        setInternetConnection,
        hasCameraPermissions,
        setCameraPermissions,
        hasLocationPermissions,
        setLocationPermissions,
        offlineData,
        setOfflineData,
      }}
    >
      {children}
    </AppContext.Provider>
  );
};

export default AppContext;

Moreover, after I modified my code, it now throws a "Too many re-renders" error and crashes (still in offline mode).

I tried several things, like changing the useEffect() hook for a useLayoutEffect(), useMemo() and even nothing at all, but the same error occurs.

The question StackOverflow identified as "duplicate" is a completely different issue, mine is simply the Context Provider not working when the app is launched without any Internet connection.

Any help would be welcome, and please take into account that I have less than 1 year of experience in React, so no need to throw fire if it's a dumb mistake.

Diocrasis
  • 1
  • 1
  • Are you sure that the error comes from useEffect from AppProvider? Try to comment out all useEffect hooks from AppProvider and try to run the app. They look fine to me, but some other code might be doing the infinite loop. – SlothOverlord Jul 11 '23 at 08:09
  • I tried removing it, using it on component mount, update and dismount, but nothing works @SlothOverlord – Diocrasis Jul 11 '23 at 10:17
  • Does this answer your question? [React Context API - persist data on page refresh](https://stackoverflow.com/questions/53453861/react-context-api-persist-data-on-page-refresh) – Abe Jul 11 '23 at 14:20
  • @Abe no, this is a completely different topic – Diocrasis Jul 13 '23 at 09:36

0 Answers0