Add an event listener to bottom tab with Expo router

48 Views Asked by At

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;
1

There are 1 best solutions below

0
Andrew Einhorn On

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])
  
  ...

  }