如何使用 React Native 导航有条件地呈现 headerLeft?

How to conditionally render headerLeft using React Native navigation?

我有一个组件 returns 一个 <Stack.Navigator> 包含几个屏幕。我还有一个自定义 headerLeft 元素,它在单击时执行一个函数。现在,如果我在 enterEmail 屏幕上,我会尝试隐藏 headerLeft,但在所有其他屏幕上都可以看到它。

在实现我自己的后退按钮之前,我只是用它来隐藏 enterEmail 屏幕上的后退按钮:

        <Stack.Screen
            name="EnterEmail"
            options={{ title: LOGIN_TITLE, headerBackVisible: false }}
            component={EnterEmail}
        />

但现在我使用的是自定义元素,这不起作用。

const AuthStack: FunctionComponent = () => {
    const navigation = useNavigation<LandingScreenNavigationProp>();

    const headerTitle = <HeaderText variant="h5">Log in</HeaderText>;

    return (
        <Stack.Navigator
            initialRouteName="Landing"
            screenOptions={{
                animation: authStackAnimation,
                headerTitleAlign: 'center',
                headerBackVisible: false,
                headerLeft: () => <NavigationBackButton onPress={() => navigation.goBack()} />,
                headerRight: () => <NavigationCloseButton onPress={() => navigation.navigate('Landing')} />,
            }}
        >
            <Stack.Screen options={{ headerShown: false }} name="Landing" component={Landing} />
            <Stack.Screen name="EnterEmail" options={{ headerTitle: () => headerTitle }} component={EnterEmail} />
            <Stack.Screen name="EnterPassword" options={{ headerTitle: () => headerTitle }} component={EnterPassword} />
            <Stack.Screen name="EnterOTP" options={{ headerTitle: () => headerTitle }} component={EnterOTP} />
            <Stack.Screen
                name="CheckYourEmail"
                options={{ headerTitle: () => headerTitle }}
                component={CheckYourEmail}
            />
        </Stack.Navigator>
    );
};

您可以使用 useLayoutEffect 删除 EnterEmail 屏幕中的 headerLeft 按钮,如下所示。

const EnterEmail = ({navigation}) => {
  useLayoutEffect(() => {
    navigation.setOptions({
      headerLeft: () => null,
    })
  }, [navigation])
}

您需要覆盖堆栈屏幕中的 group/navigator 选项。

<Stack.Screen
  name="EnterEmail"
  options={{ 
    headerTitle: () => headerTitle,
    headerLeft: {} // hide the header
  }}
  component={EnterEmail}
/>

我在导航器级别创建了一个带有徽标和背景的 snack,但堆栈屏幕覆盖了它。

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{
        headerStyle: { backgroundColor: 'papayawhip' },
        headerTitle: (props) => <LogoTitle {...props} />
        }}>
        <Stack.Screen
          name="Dashboard"
          component={Dashboard}
          options={{
          headerTitle: {}, // override
          headerStyle: { backgroundColor: 'red' } }} // override
        />
        <Stack.Screen
          name="Home"
          component={HomeScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}