Почему у объекта маршрута иногда есть состояние, а иногда нет - в реакции-навигации v5 - PullRequest
4 голосов
/ 08 февраля 2020

Старт:

<NavigationContainer>
      <Stack.Navigator>
        {
          isLoading ? <Stack.Screen name="AuthLoadingScreen" component={AuthLoadingScreen} />
          : (
          user ? (
            <Stack.Screen  name="AuthenticatedStack" component={AuthenticatedStack} options={{headerShown: false}} />
            ) : (
              <Stack.Screen  name="NotAuthenticatedStack" component={NotAuthenticatedStack} options={{headerShown: false}} />
            )
          )
        }
      </Stack.Navigator>
    </NavigationContainer>

Аутентифицированный стек:

const AuthenticatedStack = () => {
  return (
    <Drawer.Navigator initialRouteName="MainStack" drawerContent={props => <SideBar {...props} />}>
        <Stack.Screen name="MainStack" component={MainStack} options={({route}) => ({
            headerShown: shouldHeaderBeShown(route),title: getHeaderTitle(route),
          })} />
      </Drawer.Navigator>
  );
};

Основной стек содержит главный экран с навигатором вкладок и другими навигаторами, к которым я планирую перейти из боковых кнопок меню:

const MainStack = () => {
  return (
    <Stack.Navigator>
          <Stack.Screen name="main" component={MainTabNavigator} options={({route}) => ({
            headerShown: shouldHeaderBeShown(route),title: getHeaderTitle(route),
          })} />
          <Stack.Screen options={({route}) => ({
            title: getHeaderTitle(route),
          })} name="Welcome" component={WelcomeStack} />
        </Stack.Navigator>
  );
};

Навигатор главной вкладки - это всего лишь несколько вкладок:

const MainTabNavigator = () => {
  return (
    <Tab.Navigator>
      <Tab.Screen
...

Навигатор домашнего стека:

const HomeStackNavigator = ({navigation, routes}) => {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Home" component={HomeScreen} options={{
          headerLeft: () => (),
        }} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  );
};
Welcome stack:
const WelcomeStack = () => {
  return (
    <Stack.Navigator>
      <Stack.Screen options={({route}) => ({
        headerShown: shouldHeaderBeShown(route),title: getHeaderTitle(route),
      })} name="welcome" component={WelcomeScreen} />
    </Stack.Navigator>
  );
};

Я использую эти две функции, чтобы показать скрытый заголовок для двойных заголовков avoud на вкладках и для установки заголовков:

function shouldHeaderBeShown(route) {
  const routeName = route.state ? route.state.routes[route.state.index].name : 'Home';

  switch (routeName) {
    case 'Home': return false;
  }
}

function getHeaderTitle(route) {
  const routeName = route.state ? route.state.routes[route.state.index].name : 'Home';

  switch (routeName) {
    case 'Home': return 'Home';
    case 'Settings': return 'Settings';
    case 'Welcome': return 'Welcome';
  }
}

И вот я попал в проблему: Эта строка: route.state ? route.state.routes[route.state.index].name если я переключаюсь между вкладками, я получаю все правильно * Свойство 1020 * есть, и его точные заголовки установлены. Но если я из ящика перехожу к Welcome, то route не имеет свойства state, поэтому он всегда выбирает «Домой» для заголовка. Я передаю это, делая эту строку:

const routeName = route.state ? route.state.routes[route.state.index].name : route.name;

Затем отображается заголовок Welcome. Но я не понимаю, подходит ли этот обходной путь, или эти экраны можно настроить лучше?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

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


import {StackActions} from 'react-navigation';
pushAction = StackActions.push({
        routeName: 'FormsScreen',
        params: {
          id: result.id,
          flag: true,
          comments: result.note,
          type: result.type,
          date: result.created,
          accountName: result.accountName,
          accountId: result.accountId,
          accountType: result.accountType,
          bundleId: result.bundleId,
          formAnswer: JSON.parse(result.formAnswer),
        },
this.props.navigation.dispatch(pushAction);
0 голосов
/ 10 февраля 2020

Но если я из ящика перейду к Приветствию

Как вы переместитесь из ящика? Если вы осуществляете навигацию, передавая параметр screen, вы можете сделать это:

function getActiveRouteName(route) {
  // Access the tab navigator's state using `route.state`
  const routeName = route.state
    ? // Get the currently active route name in the tab navigator
      route.state.routes[route.state.index].name
    : // If state doesn't exist, we need to default to `screen` param if available, or the initial screen
      // In our case, it's "Home" as that's the first screen inside the navigator
      route.params?.screen || 'Home';

  return routeName;
}

Также кажется, что вам даже нужна эта причина, потому что у вас так много вложенных навигаторов. Может быть, попытаться уменьшить вложенность в первую очередь? https://reactnavigation.org/docs/en/nesting-navigators.html#best -practices-когда-вложенности

...