Files
RN_Template/RN_TEMPLATE/app/utils/useHeader.tsx

40 lines
1.7 KiB
TypeScript
Raw Permalink Normal View History

2026-02-05 13:16:05 +08:00
import { useEffect, useLayoutEffect } from "react"
import { Platform } from "react-native"
import { useNavigation } from "@react-navigation/native"
import { useTranslation } from "react-i18next"
import { Header, HeaderProps } from "@/components/Header"
/**
* A hook that can be used to easily set the Header of a react-navigation screen from within the screen's component.
* @see [Documentation and Examples]{@link https://docs.infinite.red/ignite-cli/boilerplate/app/utils/useHeader.tsx/}
* @param {HeaderProps} headerProps - The props for the `Header` component.
* @param {any[]} deps - The dependencies to watch for changes to update the header.
*/
export function useHeader(
headerProps: HeaderProps,
deps: Parameters<typeof useLayoutEffect>[1] = [],
) {
const navigation = useNavigation()
const { i18n } = useTranslation()
/**
* We need to have multiple implementations of this hook for web and mobile.
* Web needs to use useEffect to avoid a rendering loop.
* In mobile and also to avoid a visible header jump when navigating between screens, we use
* `useLayoutEffect`, which will apply the settings before the screen renders.
*/
const usePlatformEffect = Platform.OS === "web" ? useEffect : useLayoutEffect
// To avoid a visible header jump when navigating between screens, we use
// `useLayoutEffect`, which will apply the settings before the screen renders.
usePlatformEffect(() => {
navigation.setOptions({
headerShown: true,
header: () => <Header {...headerProps} />,
})
// intentionally created API to have user set when they want to update the header via `deps`
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [...deps, navigation, i18n.language])
}