web-dev-qa-db-ja.com

React-Navigation 3:createBottomTabNavigatorおよびcreateStackNavigatorでモーダルを開く

この質問が以前に尋ねられたことは知っていますが、古いバージョンのreact-navigationについてのみです。それ以降、いくつかの変更が加えられました。createBottomTabNavigatorにより、ボトムナビゲーターの作成がはるかに速くなり、関数jumpToIndex()は、もう存在しません。

私の質問は、Instagramのような下部タブを作成する方法です。最初、2番目、4番目、5番目のナビゲーションボタンは通常のタブナビゲーターのように機能し、中央のボタン(screen3)はモーダルscreen3Modalを開きます。

createBottomTabNavigatorcreateStackNavigatorを使用して、反応ナビゲーション3.x.xで試してみました。

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
Gabriel Winkler

まあ、私はこの問題を解決するために何時間も費やしてきました。

これが完全に機能し、テスト済みのソリューションです。

  1. タブスタックを含め、モーダルナビゲーションスタックを開くことで、アプリコンテナーを設定します。
  const FinalTabsStack = createStackNavigator(
    {
      tabs: TabNavigator,
      screen1: Screen1Navigator,
    }, {
      mode: 'modal',
    }
  )
  1. this ガイドごとにそのタブスタックでアプリコンテナーを作成する

  2. TabNavigator内のcreateBottomTabNavigator内の特定のタブ(screen3)のnullコンポーネントを返し(react-navigatorによるナビゲーションをオフにする)、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} />;
        }
      },
    }),
  1. TouchableWithoutFeedbackとonPressを使用して、カスタムタブコンポーネントScreen3Tab内で手動でクリックを処理します。 Screen3Tabコンポーネントの内部:
  <TouchableWithoutFeedback onPress={this.onPress}>
    <Your custom tab component here />
  </TouchableWithoutFeedback>

  1. OnPressディスパッチreduxイベントをキャッチしたら
  onPress = () => {
    this.props.dispatch({ type: 'NAVIGATION_NAVIGATE', payload: {
      key: 'screen3',
      routeName: 'screen3',
    }})
  }
  1. ナビゲーションサービス を使用してディスパッチされたイベントを処理します。 redux-sagaを使用しています
  NavigationService.navigate(action.payload);

少し複雑ですが動作します。

0
Oleg