React navigation focus event listener return old state

Viewed 1910

The old value is returned inside the focus event listener

how to I get the current state/value in my event listener as it is currently returning the old value

  const [organizationName, setOrganizationName] = React.useState('');

      React.useEffect(() => {
        const unsubscribeNavigationFocus = props.navigation.addListener(
          'focus',
          async () => {
        try {     
          console.log(organizationName, 'OLD VALUE');
        
    
          // }
        } catch (error) {
          console.log('inside error');
          console.log(error);
    
        } finally {
    
        }
      }
        );
    
        return unsubscribeNavigationFocus;
      }, [props.navigation]);

@react-navigation/native: "5.8.10", react": "16.13.1", react-native: "0.63.4",

3 Answers

You need to add your state to the dependency array

const [organizationName, setOrganizationName] = React.useState('');

React.useEffect(() => {
  const unsubscribeNavigationFocus = props.navigation.addListener(
    'focus',
    async () => {
      try {
        console.log(organizationName, 'OLD VALUE');

        // }
      } catch (error) {
        console.log('inside error');
        console.log(error);
      } finally {
      }
    }
  );

  return unsubscribeNavigationFocus;
}, [props.navigation, organizationName]);

Use the official ESLint plugin for React to catch such issues https://www.npmjs.com/package/eslint-plugin-react-hooks

The event listeners will only be aware of the state of the component at the initial render and will not have access to updated state values. I recommend you to use useRef to create a reference to the component state or some property of the componente state:

const [someStateVal, setSomeStateVal] = React.useState("");
  const stateRef = useRef(""); //--> data that you want to use inside the listener

  const updateState = val => {
    stateRef.current = val;
    setSomeStateVal(val);
  };

  React.useEffect(() => {
    const unsubscribeNavigationFocus = props.navigation.addListener(
      "focus",
      async () => {
        try {
          console.log(stateRef.current, "UPDATED VALUE");

        } catch (error) {
          //...
        } finally {
          //...
        }
      }
    );

    return unsubscribeNavigationFocus;
  }, [props.navigation]);

make sure to re-Add the event listeners on each render Inside The useEffect:

  1. Add Event Listener
  2. Remove Event Listener
  3. Re-Add Event Listener these steps should always be applied at each setState call.

For Example:

useEffect(() => {focusElement.addEventListener(...);
return () => {
 focusElement.removeEventListener(...)},[dependencies])

so everytime you want to setState you should re-Add the event listeners. hope this clear things out.

Related