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