Search code examples
react-nativetabsreact-navigationfocushook

How to check if a screen is focused within a Tab Stack - React Navigation


I'm creating a React Native app that uses React Navigation.

Within 1 of my tabs, I have 3 screens. If I am in any of the screens that isn't the home screen within that tab, and I tap on the tab icon, it takes me to the home screen of that tab. That's great, fantastic.

However, it doesn't trigger the useIsFocused hook and therefore doesn't run a key function that needs to run when the screen is no longer displayed.

I would ideally like a way to find out if the tab has been pressed or the screen is unfocused from within my screen because I need to reference things on that screen.

I found this in the docs:

React.useEffect(() => {
  const unsubscribe = navigation.addListener('tabPress', (e) => {
    // Prevent default behavior
    e.preventDefault();

    // Do something manually
    // ...
  });

  return unsubscribe;
}, [navigation]);

But this doesn't seem to work within the screen. Tapping the tab doesn't trigger the useEffect.

This is my current code. Essentially, I am refetching some data for my screen every 10 seconds. When navigating away from my screen, I would like that interval to stop running. It works in every way apart from when tapping the tab icon in the tab navigation bar that this screen is a part of.

function setUpdateQueries() {
  let value = setInterval(refetchFunction, 10000, "active");
  setRefresh(value);
  console.log(value);
}
 
const isFocused = useIsFocused();
const navigation = useNavigation();
 
useEffect(() => {
  if (isFocused) {
    setUpdateQueries();
  }
  else {
    console.log("Clearing", refresh);
    clearInterval(refresh)
  }
},[isFocused])

Solution

  • So after leaving it and coming back to it, the answer is simple in their docs. Don't use useIsFocused(). Rather, use the useFocusEffect() hook like so:

    useFocusEffect(
        React.useCallback(() => {
          let value
          const firstRefresh = refetchFunction("active")
          value = setInterval(refetchFunction, 10000, "active");
          console.log(value);
          
          const unsubscribe = () => {
            console.log("Clearing", value);
            clearInterval(value)
          }
    
          return () => unsubscribe();
        }, [])
      );
    

    This picks up the tab press as well.