skip to Main Content

I would like to add an event listener to one of my bottom tabs so I can trigger events when the user clicks on that tab. React navigation had a function navigator.addListener which allowed me to track this (see code below)

Does Expo router have some sort of equivalent?

import React, { useEffect } from 'react';
import { useNavigation } from '@react-navigation/native';

function MyTabScreen() {
  const navigation = useNavigation();

  useEffect(() => {
    const unsubscribe = navigation.addListener('tabPress', (e) => {
      console.log('Tab icon tapped');
      // Add your logic here
    });

    return unsubscribe;
  }, [navigation]);

  return (
    // Your tab screen content goes here
  );
}

export default MyTabScreen;

2

Answers


  1. Chosen as BEST ANSWER

    Ok, so I have found a solution to this.

    The Tabs component from expo router has got a property called screenListeners, and you just need to implement the tabPress listener.

    In my case, when the tabPress gets hit, I establish which tab was pressed, and if it is my tab of interest, I toggle a value in state. Then, in turn, I employ a useEffect in the tab's actual implementation to listen for that toggle, and execute the code I need to there.

    Inside my Tabs _layout.tsx

    import { Tabs } from 'expo-router/tabs'
    import useStore from 'src/store'
    
    export default function TabLayout() {
      const { stacksTabPress, toggleStacksTabPress } = useStore()
    
      return (
        <Tabs
          initialRouteName={'stacks'}
          screenOptions={}
          screenListeners={{
            // Monitor tab press and if 'test' tab is pressed, toggle value in zustand to trigger refetching of data from server
            tabPress: (e) => {
              const parts = e.target.split("-");
              const result = parts[0];
              if (result === 'test') {
                toggleStacksTabPress()
              }
            }
          }}
        >
          <Tabs.Screen
            name="test"
        />
        )}
    

    Inside my test index.tsx file

    const test = () => {
    
      const { stacksTabPress } = useStore()
    
      useEffect(() => {
        console.log("#### Execute my code from the tab press here ... ")
      }, [stacksTabPress])
      
      ...
    
      }
    

  2. This is what i did

    in my _layout.tsx Tabs tag

          screenListeners={{
        tabPress: (e) => {
          const target = e.target?.split("-")[0];
          if (target == "index") {
            EventRegister.emit(eventConfig.FEED_TAB_CLICKED);
          }
        },
      }}
    

    Then in your flatlist function

    const focused = useIsFocused();
    const ref = useRef<FlatList | null>(null);

      useFocusEffect(
    useCallback(() => {
      const feedListener = EventRegister.on(
        eventConfig.FEED_TAB_CLICKED,
        () => {
          if (focused) {
            ref.current?.scrollToOffset({ offset: 0, animated: true });
          }
        }
      );
      return () => EventRegister.removeEventListener(String(feedListener));
    }, [focused])
    

    );

      <FlatList
      ref={ref}...
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search