Home > database >  React Native useEffect not run when app first opened
React Native useEffect not run when app first opened

Time:01-04

I am trying to make an app where the USER_ID is loaded from the device's local storage if found, otherwise, a new id is generated and stored in the local storage. I am trying to make use of React useContext() to make the USER_ID visible to the whole app after it is first run.

import React, {useEffect, useState} from 'react';

import AsyncStorage from '@react-native-async-storage/async-storage';
import uuid from 'react-native-uuid';

export const UserIdContext = React.createContext('undef');

export const UserIdProvider = ({children}) => {
  const [userId, setUserId] = useState('');

  useEffect(() => {
    async function getOrInitUserId() {
      try {
        let temp = await AsyncStorage.getItem('USER_ID');
        if (temp == null) {
          temp = uuid.v4();
          await AsyncStorage.setItem('USER_ID', uuid.v4());
          console.log('USER_ID Generated: '   temp);
        } else {
          console.log('USER_ID Found: '   temp);
        }
        setUserId(temp);
      } catch (error) {
        console.error(error);
      }
    }

    if (!userId) {
      getOrInitUserId();
    }
  });

  return (
    <UserIdContext.Provider value={userId}>{children}</UserIdContext.Provider>
  );
};

export const useUserId = () => React.useContext(UserIdContext);

The provider is used as below:

const App = () => {
  useEffect(() => {
    ....
  });

  return (
    <UserIdProvider>
      ...contents of app...
    </UserIdProvider>
  );
};

export default App;

However, the useEffect() of < UserIdProvider /> is not run as the app is launched for the first time after being installed on a device, as there is no log on the console. After the app is closed/quit and relaunched, the console log a USER_ID found, instead of USER_ID generated.

CodePudding user response:

Add 2nd argument as [] so it will render only once. Otherwise, it will render every time when any state will be updated.

 const App = () => {
      useEffect(() => {
        ....
      },[]);
    
      return (
        <UserIdProvider>
          ...contents of app...
        </UserIdProvider>
      );
    };

export default App;

CodePudding user response:

In order to trigger useEffect when first run you should enter [] as prop like this:

useEffect(() => {
    async function getOrInitUserId() {
      try {
        let temp = await AsyncStorage.getItem('USER_ID');
        if (temp == null) {
          temp = uuid.v4();
          await AsyncStorage.setItem('USER_ID', uuid.v4());
          console.log('USER_ID Generated: '   temp);
        } else {
          console.log('USER_ID Found: '   temp);
        }
        setUserId(temp);
      } catch (error) {
        console.error(error);
      }
    }

    if (!userId) {
      getOrInitUserId();
    }
  }, []);
  • Related