React Native: установите заголовки экранов навигации React

#javascript #reactjs #typescript #react-native #mobile

#javascript #reactjs ( реакция ) #машинописный текст #react-native #Мобильный #reactjs #typescript

Вопрос:

Я хочу иметь вкладки из BottomTabsNavigator и заголовок из StackNavigator в случае jwt = true.

Кто-нибудь знает, как я могу это сделать?

Вы можете найти мой навигационный jsx ниже.

Если я не сообщил достаточно подробностей, пожалуйста, спросите меня.

Спасибо.

 <NavigationContainer>
  {jwt ? (
    <Bottom.Navigator>
      <Bottom.Screen
        name="ToDoList"
        component={Home}
        options={{
          title: "Not To Do List",
          tabBarIcon: ({ color }: any) => (
            <Icon name="check" color={color} size={28} />
          ),
        }}
      />

      <Bottom.Screen
        name="NotToDoList"
        component={NotToDo}
        options={{
          title: "To Do List",
          tabBarIcon: ({ color }: any) => (
            <FIcon name="ban" color={color} size={28} />
          ),
        }}
      />

      <Bottom.Screen
        name="Profile"
        component={Profile}
        options={{
          tabBarIcon: ({ color }: any) => (
            <FIcon name="user" color={color} size={28} />
          ),
        }}
      />
    </Bottom.Navigator>
  ) : (
    <Stack.Navigator>
      <Stack.Screen
        name="SignIn"
        component={SignIn}
        options={{ ...centerTitle("Sign In"), headerLeft }}
      />
      <Stack.Screen
        name="SignUp"
        component={SignUp}
        options={{ ...centerTitle("Sign Up"), headerLeft }}
      />
    </Stack.Navigator>
  )}
</NavigationContainer>
  

Комментарии:

1. Таким образом, условный рендеринг jwt выглядит нормально. Вы хотите макет, в котором у вас есть обе вкладки и заголовок стека, но только если jwt значение true? Что вы хотите отобразить, если jwt есть false ?

2. Извините, если я не слишком хорошо объяснил. Итак, я хочу иметь заголовок стека на нижних вкладках, внизу — createBottomTabNavigator для нижних вкладок, таких как Instagram, но у него нет классического заголовка из createStackNavigator. Есть ли в любом случае заголовок из маршрута createStackNavigator на маршруте createBottomTabNavigator?

Ответ №1:

Если вы хотите отобразить заголовок навигатора стека для экранов вашего нижнего навигатора вкладок, вы можете вложить свой навигатор вкладок в другой навигатор стека.

Это общая структура, которую вы могли бы применить:

 NavigationContainer
...MainNavigator (StackNavigator): show if `jwt`
......BottomNavigator (TabNavigator and Screen of MainNavigator)
...LoginNavigator (StackNavigator) show if not `jwt`  
  

Я привел более общий воспроизводимый пример, чтобы проиллюстрировать суть:

 import React from 'react';
import {Text, View} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';

const Main = createStackNavigator();
const Login = createStackNavigator();
const Tab = createBottomTabNavigator();

const Screen1 = () => {
  return <Text>Screen1</Text>;
};

const Screen2 = () => {
  return <Text>Screen1</Text>;
};

const LoginPage = () => {
  return <Text>LoginPage</Text>;
};

function TabNavigator() {
  return (
    <Tab.Navigator>
      <Tab.Screen name="Screen1" component={Screen1} />
      <Tab.Screen name="Screen2" component={Screen2} />
    </Tab.Navigator>
  );
}

function MainNavigator() {
  return (
    <Main.Navigator>
      <Main.Screen name="Tabs" component={TabNavigator} />
    </Main.Navigator>
  );
}

function LoginNavigator() {
  return (
    <Login.Navigator>
      <Login.Screen name="Login" component={LoginPage} />
    </Login.Navigator>
  );
}

const App = () => {
  const jwt = true; // in your case this value is dynamic of course
  return (
    <NavigationContainer>
      {jwt ? <MainNavigator /> : <LoginNavigator />}
    </NavigationContainer>
  );
};

export default App;
  

Обновить

Если вы хотите, чтобы название заголовка навигатора стека совпадало с названиями экранов, которые у вас есть в навигаторе вкладок, или если вы хотите, чтобы имя было динамическим другим способом на основе названий вкладок, мы можем использовать getFocusedRouteNameFromRoute , которые предоставляет react navigation.

getFocusedRouteNameFromRoute импортируется из @react-navigation/native так же, как NavigationContainer есть.

 // First we create a function like this:
function getHeaderTitle(route) {
  // In case the focused route is not found, assume it's the first screen, Screen1 in this example.
  return getFocusedRouteNameFromRoute(route) ?? 'Screen1';
}

// Then we can use it like this:
function MainNavigator() {
  return (
    <Main.Navigator>
      <Main.Screen
        options={({route}) => ({
          headerTitle: getHeaderTitle(route),
        })}
        name="Tabs"
        component={TabNavigator}
      />
    </Main.Navigator>
  );
}
  

Вы можете прочитать об этом здесь, в документации: https://reactnavigation.org/docs/screen-options-resolution/#setting-parent-screen-options-based-on-child-navigators-state .

Комментарии:

1. Это работает! Но у меня есть заголовок «Вкладки» на каждой странице, как я могу их настроить?

2. В настоящее время заголовок устанавливается на основе name реквизита экрана внутри MainNavigator . Вы хотите, чтобы заголовок заголовка был текущей активной вкладкой? Если это так, я обновил ответ, чтобы показать, как вы могли бы сделать заголовок динамическим на основе имен дочерних маршрутов (названия экранов навигатора вкладок в этом примере).

3. Я добавил это. Я хотел основываться на имени, но я добавил функцию для помещения пробела перед каждым символом верхнего регистра, кроме первого. Большое спасибо за помощь!!! Я не смог бы сделать это в одиночку.