React Navigation 5 Как отобразить экраны стека ящиков?

Я пытаюсь создать динамический ящик, у меня есть StackItens (маршруты), такие как:

import React from 'react';
import Home from '../screens/home/Index';
import ATR from '../screens/atr/Index';

const stackNavigItems = [
  {
    group: 'Home',
    name: 'Home',
    component: Home,
    icon: 'home',
    iconType: 'FontAwesome',
    label: 'Principal',
    hideMenu: false,
    screenComponent: props => {
      return <Home {...props} />;
    },
  },
  {
    group: 'Home',
    name: 'ATR',
    component: ATR,
    icon: 'book',
    iconType: 'Ionicons',
    label: 'ATR',
    hideMenu: false,
    screenComponent: props => {
      return <ATR {...props} />;
    },
  },
];

export {stackNavigItems};

И в моем содержимом ящика я отображаю эти элементы и отлично работаю. Но когда я отображаю те же элементы внутри навигатора, используя этот код:

<PaperProvider theme={theme}>
  <AuthContext.Provider value={authContext}>
    <NavigationContainer theme={theme}>
      <Drawer.Navigator drawerContent={props => <DrawerContent {...props} />}>
    {stackNavigItems.map(r => {
      return (
        <Drawer.Screen
          key={r.name}
          name={r.name}
          component={({navigation}) => (
            <Stack.Navigator
              initialRouteName="Home"
              headerMode="screen"
              screenOptions={screenOptions}>
              <Stack.Screen
                name={r.name}
                component={props => <r.screenComponent {...props} />}
                options={{
                  title: r.label,
                  headerLeft: () => (
                    <Icon.Button
                      name="ios-menu"
                      size={IconStyles.size}
                      backgroundColor={AppStyles.color.main}
                      onPress={() => {
                        navigation.openDrawer();
                      }}
                    />
                  ),
                }}
              />
            </Stack.Navigator>
          )}
        />
      );
    })}
  </Drawer.Navigator>
    </NavigationContainer>
  </AuthContext.Provider>
</PaperProvider>

Приложение всегда показывает мне это предупреждение, а заголовок в два раза больше:

введите описание изображения здесь

Я пробовал так много способов передать функцию () перед компонентом, но ничего не работает. Если я отключу предупреждение, приложение будет работать без отображения предупреждения, но иногда размер заголовка удваивается при использовании, как на картинке.




Ответы (1)


Вы можете избежать использования встроенных функций, создав дополнительный компонент и передав его обычным образом и передав id элемента навигации через initialParams дополнительному компоненту:

const StackNavigator = ({route}) => {
  const navigationItem = stackNavigItems[route.params?.navigationItemId];
  return (
    <Stack.Navigator initialRouteName="Home" headerMode="screen">
      <Stack.Screen
        name={navigationItem.name}
        component={navigationItem.screenComponent}
        options={{
          title: navigationItem.label,
          headerLeft: () => null,
        }}
      />
    </Stack.Navigator>
  );
};

function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator drawerContent={(props) => null}>
        {stackNavigItems.map((r) => {
          return (
            <Drawer.Screen
              key={r.name}
              name={r.name}
              component={StackNavigator}
              initialParams={{navigationItemId: r.id}}
            />
          );
        })}
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

Поэтому для этого подхода вам нужно добавить id опору к объектам внутри stackNavigItems:

const stackNavigItems = [
  {
    id: 0,
    group: 'Home',
    name: 'Home',
    component: Home,
    icon: 'home',
    iconType: 'FontAwesome',
    label: 'Principal',
    hideMenu: false,
    screenComponent: (props) => {
      return <Home {...props} />;
    },
  },
  {
    id: 1,
    group: 'Home',
    name: 'ATR',
    component: ATR,
    icon: 'book',
    iconType: 'Ionicons',
    label: 'ATR',
    hideMenu: false,
    screenComponent: (props) => {
      return <ATR {...props} />;
    },
  },
];

Я опустил некоторый несвязанный код, чтобы сделать этот пример более читабельным.

person Bas van der Linden    schedule 25.09.2020
comment
Спасибо за ответ, но это тоже не сработало. - person rodolfo; 30.09.2020
comment
Ты мой ангел!!! Работал!!! Большое спасибо за ваше время и терпение. - person rodolfo; 02.10.2020
comment
Как вы предложили, я удаляю вопрос. - person rodolfo; 02.10.2020