Skip to main content
‹ Tabs
Hook

useTabPress()

Called when the tab of this screen is pressed while the tab shows it; wasSelected tells a second press, on which apps scroll to the top. The handler can change on every render.

SectionTabsDraftDocumented, not reviewed yet: the API can change.
Import
import { useTabPress } from '@apexnative/navigation';

useTabPress calls a handler when the user taps the tab of this screen, while the screen is the one the tab shows. It is how a tab's screen reacts to a tap on its own tab: refetch the feed, reset a filter, count the taps. You call it in a component of a screen.

Usage​

src/screens/Inbox.tsx
import { FlatList, Text } from 'react-native';
import { defineScreen, useTabPress } from '@apexnative/navigation';
import { useMessages } from '../data'; // your own data hook

function Inbox() {
const { messages, refetch } = useMessages();

useTabPress(({ wasSelected }) => {
if (wasSelected) refetch();
});

return (
<FlatList
data={messages}
renderItem={({ item }) => <Text>{item.subject}</Text>}
/>
);
}

export const InboxScreen = defineScreen({ component: Inbox });

The user is on Inbox and taps the Inbox tab again: the list scrolls to the top, as the platforms do by themselves, and the messages load again. A tap that switches to Inbox from another tab doesn't reload: wasSelected is false there.

iOS
Android

Signature​

function useTabPress(handler: TabPressHandler): void
Defined in src/api/hooks/screenHooks.ts ↗

It takes one function and returns nothing. The handler can be a new function on every render: the hook always calls the latest one, so it sees the current props and state without a dependency list. It stops listening when the component unmounts.

The press​

The handler gets a TabPressEvent:

wasSelected​

wasSelected: boolean
Typeboolean Required.PlatformsiOSiPadOSAndroid

true for a tap on the tab that was already selected: the second tap, which apps use to scroll to the top or reload. false for the tap that switched to this tab from another one.

index​

index: number
Typenumber Required.PlatformsiOSiPadOSAndroid

The tab's place in Tabs(…), from 0, in the order the layout lists them, also when the user rearranged the tabs on iPad.

screenId​

screenId?: string
TypestringPlatformsiOSiPadOSAndroid

The id of the screen on top of the tab's stack: this screen, since the hook hears only the taps that reach it.

Which screen hears the tap​

The tap goes to the screen on top of the tab's stack at the moment of the tap. A screen under a pushed one doesn't hear it:

The tab showsA tap on the selected tab
Inbox aloneInbox's handler runs with wasSelected: true; the list scrolls to the top.
Inbox → ChatChat's handler runs; then the stack goes back to Inbox. Inbox's doesn't run.

The second row is popToRootOnPress, on by default. A screen that wants every tap on its tab, whatever is on top, listens at the tab instead, with Tab().onPress().

What it is not for​

  • Scrolling to the top. Both platforms do it on a second tap, unless Tab().popToRootOnPress(false). A handler that scrolls too would scroll twice.
  • Changing what a tap does. The native side has acted when the handler runs: the tab is selected, the stack went back. To keep a tap from selecting the tab, use Tab().selectOnPress(false).
  • Code outside a screen. It throws in a component that isn't in a screen: "This hook is for the screens of createNavigation". Outside React, listen with listeners.tabPressed of createNavigation or navigation.on. See Every event.
  • Screens that aren't in tabs. In a modal or a root without tabs the handler never runs.

iPadOS A pick in the iPad sidebar counts as a tap on the tab.

See also​

Generated from the types and their comments. Edit the source ↗