skip to Main Content

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.

2

Answers


  1. 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;
    
    Login or Signup to reply.
  2. 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();
        }
      }, []);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search