'react native state is updated but functions still using the initial state set at the time of mounting

In my react native functional component, the state gets updated but when I want to use this state inside a function (for e.g, to send data to API), it uses the initial state only.

imports...

const Component = ({ navigation }) => {
  const [ids, setIds] = useState([1,2]);

  useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: () => <HeaderRight 
        onPress={() =>
          console.log(ids); // this logs initial state, i.e, [1,2]
          updateIdsToServerViaAPI(); // and therefore I'm unable to update ids using this method
        }
      />
    });
  }, [navigation]);

  const updateIdsToServerViaAPI = async () => {} // function that takes updated ids from state.

  const onPress = async () => {
    const newIds = [...ids, 3, 4];
    setIds(newIds);
  }

  const onPressInsideComp = () => {
    console.log(ids);
    // here updated ids gets logged.
  }

  return (
    <View>
      <Button onPress={onPress} />
      {ids.map(id => (
        <Text key={id}>{id}</Text> {\* Here you will see 4 texts after pressing button, that means state gets updated*\}
      )}
      <Button onPress={onPressInsideComp} />
    </View>
  );
}

Seems like this issue happens only when functions are called inside useLayoutEffect or useEffect but when I call onPressInsideComp from the button inside the component, it logs properly!

I am badly stuck on this weird issue !!



Solution 1:[1]

In your code, the console.log(ids) is resolved at the moment of the function definition, and not at execution time, so it takes the reference you get in the definition const [ids, setIds} = useState([1,2]).

Maybe just try to get your ids with a function of state instead of using a variable that has been defined before:

  const [ids, setIds] = useState([1,2]);
  const get_ids = () => this.state.ids;
  useLayoutEffect(() => {
    navigation.setOptions({
      headerRight: () => <HeaderRight 
        onPress={() =>
          console.log(get_ids());
          updateIdsToServerViaAPI();
        }
      />
    });
  }, [navigation]);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peterrabbit