React-Navigation 3: Откройте модальный с помощью createBottomTabNavigator и createStackNavigator - PullRequest
0 голосов
/ 15 февраля 2019

Я знаю, что этот вопрос задавался ранее, но только для более старых версий реагировать на навигацию.С тех пор несколько вещей изменились.createBottomTabNavigator значительно ускоряет создание нижнего навигатора, а функция jumpToIndex() больше не существует.

Мой вопрос - как создать нижнюю вкладку в стиле Instagram, где первая,вторая, четвертая и пятая навигационные кнопки действуют как обычные навигаторы на вкладках, а средняя кнопка (screen3) открывает модальный режим screen3Modal.

Я пробовал это в реагирующей навигации 3.xx, используя createBottomTabNavigatorи createStackNavigator.

import React, { Component, } from 'react';
import { createBottomTabNavigator, createStackNavigator, createAppContainer, } from 'react-navigation';
import { Screen1, Screen2, Screen3, Screen4, Screen5 } from './screens';

const TabNavigator = createBottomTabNavigator({
  screen1: { screen: Screen1, },
  screen2: { screen: Screen2, },
  screen3: { 
    screen: () => null, 
    navigationOptions: () => ({
      tabBarOnPress: () => this.props.navigation.navigate('screen3Modal')
    })
  },
  screen4: { screen: Screen4, },
  screen5: { screen: Screen5, },
});

const StackNavigator = createStackNavigator({
  Home: { screen: TabNavigator },
  screen3Modal: { screen: Screen3, },
},
{
  initialRouteName: 'Home',
});

const StackNavigatorContainer = createAppContainer(StackNavigator);

export default class App extends Component {
  render() {
    return <StackNavigatorContainer />;
  }
}

Этот код создает навигацию по вкладкам и модальную навигацию.Модал можно открыть с другого экрана, но он не работает из навигатора вкладок.Я получаю сообщение об ошибке undefined is not an object (evaluating '_this.props.navigation')

Ответы [ 4 ]

0 голосов
/ 02 августа 2019

Я нашел лучшее решение на основе этой проблемы github .Вам просто нужно добавить в конкретную конфигурацию вкладки, в вашем случае screen3 событие navigationOptions (у вас это уже было), вы были довольно близки, но вам нужно было получить навигацию в качестве параметра, потому что нет никакого контекста дляthis как вы его использовали.Чтобы исправить первый код, который вы написали, я бы изменил его на это, и он будет работать:

navigationOptions: ({ navigation }) => ({
  tabBarOnPress: ({ navigation }) => {
    navigation.navigate("screen3Modal");
  }
})
0 голосов
/ 16 февраля 2019

Я нашел относительно простое решение: скройте исходную панель навигации с помощью display:"none"

const TabNavigator = createBottomTabNavigator(
  {
    screen1: Screen1,
    screen2: Screen2,
    screen4: Screen4,
    screen5: Screen5,
  }, {
    tabBarOptions: {
      style: { display: "none", }
    }
  },
);

const StackNavigator = createStackNavigator(
  {
    Home: TabNavigator,
    screen3: Screen3
  }, {
    mode: 'modal',
  }
)

export default createAppContainer(StackNavigator);

и создайте новую панель навигации на каждом экране

<View style={{ flexDirection: "row", height: 50, justifyContent: "space-evenly", alignItems: "center", width: "100%" }}>
  <TouchableOpacity onPress={() => this.props.navigation.navigate("screen1")}><Text>1</Text></TouchableOpacity>
  <TouchableOpacity onPress={() => this.props.navigation.navigate("screen2")}><Text>2</Text></TouchableOpacity>
  <TouchableOpacity onPress={() => this.props.navigation.navigate("screen3")}><Text>3</Text></TouchableOpacity>
  <TouchableOpacity onPress={() => this.props.navigation.navigate("screen4")}><Text>4</Text></TouchableOpacity>
  <TouchableOpacity onPress={() => this.props.navigation.navigate("screen5")}><Text>5</Text></TouchableOpacity>
</View>
0 голосов
/ 26 февраля 2019

Ну, я потратил часы на решение этой проблемы.

Вот полностью работающее и протестированное решение:

  1. Настройте контейнер приложения, включив стек вкладок и открываясьстек модальной навигации:
  const FinalTabsStack = createStackNavigator(
    {
      tabs: TabNavigator,
      screen1: Screen1Navigator,
    }, {
      mode: 'modal',
    }
  )

Создание контейнера приложения с этим стеком вкладок для этой направляющей

Внутри TabNavigator в createBottomTabNavigator возвращаемом нулевом компоненте для конкретной вкладки(screen3) (для отключения навигации по реагирующему навигатору) и обработайте вкладку вручную внутри defaultNavigationOptions, создав для нее пользовательский компонент.

  const TabNavigator = createBottomTabNavigator({
    screen1: Screen1Navigator,
    screen2: Screen2Navigator,
    screen3: () => null,
    screen4: Screen4Navigator,
    screen5: Screen5Navigator,
}
    defaultNavigationOptions: ({ navigation }) => ({
      mode: 'modal',
      header: null,
      tabBarIcon: ({ focused }) => {
        const { routeName } = navigation.state;
        if (routeName === 'screen3') {
          return <Screen3Tab isFocused={focused} />;
        }
      },
    }),
Обрабатывать щелчок вручную внутри пользовательского компонента вкладки Screen3Tab с помощью TouchableWithoutFeedback & onPress.Внутренний компонент Screen3Tab:
  <TouchableWithoutFeedback onPress={this.onPress}>
    <Your custom tab component here />
  </TouchableWithoutFeedback>

После того, как вы перехватили событие редукции отправки onPress
  onPress = () => {
    this.props.dispatch({ type: 'NAVIGATION_NAVIGATE', payload: {
      key: 'screen3',
      routeName: 'screen3',
    }})
  }
Обработка отправленного события с использованием Служба навигации .Я использую redux-saga для этого
  NavigationService.navigate(action.payload);

Немного сложно, но работает.

0 голосов
/ 15 февраля 2019

Вы можете обернуть все внутри одного и того же StackNavigator, чтобы вы могли легко перемещаться по другим маршрутам.Здесь я передаю screen3 как маршрут по умолчанию, но вы можете изменить его на любой другой.

import React, { Component, } from 'react';
import { createBottomTabNavigator, createStackNavigator, createAppContainer, } from 'react-navigation';
import { Screen1, Screen2, Screen3, Screen4, Screen5 } from './screens';

const TabNavigator = createBottomTabNavigator({
  screen1: { screen: Screen1, },
  screen2: { screen: Screen2, },
  screen3: { screen: () => null, }, //this.props.navigation.navigate('screen3Modal')
  screen4: { screen: Screen4, },
  screen5: { screen: Screen5, },
});

const StackNavigator = createStackNavigator({
  Home: { screen: TabNavigator },
  screen3Modal: { screen: Screen3, },
},
{
  initialRouteName: 'screen3Modal',
});

const StackNavigatorContainer = createAppContainer(StackNavigator);

export default class App extends Component {
  render() {
    return <StackNavigatorContainer />;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...