Как установить всегда первый экран Stack Navigator внутри Tab Navigator React Navigation 5

React Navigation 5

Я создал StackNavigator внутри TabNavigator, и навигация между домашним экраном и другими экранами работает. Но проблема в том, что когда я перехожу с Tab2 на Tab1, я ожидаю, что Tab1 всегда будет показывать мне первый экран StackNavigator.

tab1
   -> Stack
        -screen1
        -screen2
tab2

Я нахожусь на screen2, а затем перехожу к tab2, после чего я возвращаюсь к Tab1, я хочу всегда отображать screen1.

Я пытаюсь использовать

OnTabPress({navigation})=>{
    navigation.navigate("stackName",{
     screen: "screen1"
   }).
}

Его работа, но сначала покажите мне screen2, а затем перейдите к screen1. Есть ли другое решение. https://snack.expo.io/@usamasomy/groaning-donut


person osama somy    schedule 28.04.2020    source источник


Ответы (2)


Используйте unmountOnBlur: true в опциях. Например.

<Tab.Screen
        name="Stack1"
        component={Stack1}
        options={{
          tabBarLabel: "Stack1",
          unmountOnBlur: true,
        }}
      />

Поэтому, когда вы уходите с этой вкладки и находитесь на экране 2 из Stack1, вы всегда будете попадать на первый экран этого stackNavigator, когда вернетесь на эту вкладку.

person Abhishek Shakya    schedule 04.11.2020

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

initialRouteName= "NAME" - это ключевое слово, чтобы убедиться, что у вас есть значение по умолчанию, и убедитесь, что вы используете navigate() push() pop() соответственно.

Во-первых, создайте настраиваемую панель вкладок, чтобы мы могли писать свои собственные функции, выполняемые onPress

function MyTabBar({ state, descriptors, navigation }) {
  return (
    <View style={{ flexDirection: 'row' }}>
      {state.routes.map((route, index) => {
        const { options } = descriptors[route.key];
        const label =
          options.tabBarLabel !== undefined
            ? options.tabBarLabel
            : options.title !== undefined
            ? options.title
            : route.name;

        const isFocused = state.index === index;

        const onPress = () => {
            navigation.reset({
              index: 0,
              routes: [{ name: 'Screen1' }],
            }) 

        if (!isFocused && !event.defaultPrevented) {
            navigation.navigate(route.name);
          }      
            }}
        const onLongPress = () => {
          navigation.emit({
            type: 'tabLongPress',
            target: route.key,
          });
        };

Затем в TabScreens переопределите исходный TabBar в Tab.Navigator, используя tabBar=..., затем вызовите navigation.reset() с index:0 и routes:{{name: 'Screen1'}} каждый раз, когда нажимается MyTabBar.

const TabScreens = ()=>{
  return(
    <Tab.Navigator  tabBar={props => <MyTabBar {...props} />} initialRouteName="Tab1Screens" >
      <Tab.Screen 
        name      = "Tab1Screens"
        component = {Tab1Screens}
      />
      <Tab.Screen
        name      = "Tab2Screens"
        component = {Tab2Screens}
      />
    </Tab.Navigator>
  )
}

        return (
          <TouchableOpacity
            accessibilityRole="button"
            accessibilityStates={isFocused ? ['selected'] : []}
            accessibilityLabel={options.tabBarAccessibilityLabel}
            testID={options.tabBarTestID}
            onPress={onPress}
            onLongPress={onLongPress}
            style={{ flex: 1 }}
          >
            <Text style={{ color: isFocused ? '#673ab7' : '#222' }}>
              {label}
            </Text>
          </TouchableOpacity>
        );
      })}
    </View>
  );
}

Это можно значительно улучшить, например:

-some logic before `navigation.reset()`

-Accessing onPress without creating a new component 

-etc..

наконец, закуска доступна здесь: https://snack.expo.io/@karammarrie/customtabbar

person forthelulx    schedule 28.04.2020
comment
Прежде всего, я очень благодарен за ваш любезный ответ. InitialRouteName работает только в первый раз. Затем он не работает, и я не могу использовать Pop, когда я перехожу с экрана 1 - ›Экран 2. Возможно ли, когда я перейду на экран 2, например navigation.navigate("Screen2"), прежде чем перейти к экрану, я перейду на экран 1 в начало стека, а когда я перейду с вкладки 2 - ›вкладка 1, он снова покажет мне экран 1. Спасибо. - person osama somy; 28.04.2020
comment
Спасибо за его работу. Но есть ли другой способ добиться этого результата без настраиваемой панели вкладок Может быть внутри <Tab.screen listeners ={ ({navigation})=>({ tabPress: (e)=>{ e.preventDefault; *May be Here* } }) } /> - person osama somy; 30.04.2020
comment
Если он работает так, как вы просили, примите ответ, чтобы другие сочли его полезным. В любом случае, я обязательно проверю то, что вы предложили. - person forthelulx; 30.04.2020
comment
<Tab.Screen name="Stack1" component={Stack1} listeners ={ ({navigation})=>({ tabPress: (e)=>{ e.preventDefault; navigation.dispatch( navigation.reset({ index: 0, routes: [{screen: 'screen1'}] }) ) } }) } /> этот код также дает мне тот же результат, что и ваш код, без изменения стиля панели вкладок, но одним исключением в коде Boht является то, что он всегда повторно отображает компонент. Я получу некоторые данные из api и в соответствии с приведенным выше повторным преобразованием компонента кода и данными, полученными снова. как принять твой ответ? - person osama somy; 30.04.2020
comment
Это делает! как вы можете видеть в моем ответе, это можно значительно улучшить, получив доступ к onPress без создания нового компонента. что вы делаете с частью слушателей. Мне лично нравится создавать компоненты, поэтому у меня больше контроля. Если вы прокрутите до начала моего ответа, рядом с номером должен быть флажок, чтобы отметить его как принятый, сделайте это (: - person forthelulx; 30.04.2020
comment
Если вы хотите сохранить состояние без повторного рендеринга вызовов API, вам понадобятся какие-то состояния сохранения, наиболее распространенным способом является Redux. официальные документы: react-redux.js.org - person forthelulx; 30.04.2020
comment
Я очень ценю ваш ответ. Вы также расширили мои знания. Еще раз спасибо. - person osama somy; 30.04.2020