(React-native-tab-view) Используете navigation.navigate в TabBar?

Я новичок в React Native и создаю приложение для одного из наших клиентов.

Я создал экран, на котором отображается список имен, которые могут отображаться в алфавитном порядке или сгруппированы по категориям. Я использовал компонент react-native-tab-view, чтобы заставить эту работу работать. Каждая из двух вкладок отображает свой собственный компонент экрана, ScreenMapAlpha (показывает FlatList) и ScreenMapCategory (показывает SectionList).

Для каждой renderItem опоры этих списков я хотел сделать каждый элемент доступным для кликов с помощью TouchableOpacity, превратив его в страницу с подробностями, однако мне не удалось заставить работать функцию navigation.navigate (), поскольку я продолжаю получать это сообщение:

TypeError: undefined не является объектом (оценка '_this3.props.navigation.navigate')

Я читал документацию Github response-native-tab-view но я не смог найти способ передать объект навигации в оба компонента экрана Alpha / Category, чтобы он работал.

Мой код выглядит так:

import * as React from 'react';
import { StyleSheet, Text, View, Dimensions } from 'react-native';
import ScreenMapAlpha from '../screens/map_alpha';
import ScreenMapCategory from '../screens/map_cat';
import { TabView, TabBar, SceneMap } from 'react-native-tab-view';

const initialLayout = { width: Dimensions.get('window').width };

const renderTabBar = props => (
  <TabBar
    {...props}
    indicatorStyle={{ backgroundColor: '#fff' }}
    style={{ backgroundColor: '#c00' }}
  />
);

export default function ScreenMap({ navigation }) {
    const [index, setIndex] = React.useState(0);
    const [routes] = React.useState([
        { key: 'first', title: 'Alphabetical' },
        { key: 'second', title: 'Category' }
    ]);

    const renderScene = SceneMap({
        first: ScreenMapAlpha,
        second: ScreenMapCategory
    });

    return (
        <TabView
            navigationState={{index, routes}}
            renderScene={renderScene}
            onIndexChange={setIndex}
            renderTabBar={renderTabBar}
            initialLayout={initialLayout}
            navigation={navigation}
        />
    )  
}

map_alpha.js

import React, { useEffect, useState } from 'react';
import { StyleSheet, View, Text, FlatList, Image, TouchableOpacity } from 'react-native';
import TenantListAlpha from '../shared/tableTenantAlpha';

export default function ScreenMapAlpha({ navigation }) {       
    return (
        <View style={styles.container}>
            <TenantListAlpha navigation={navigation} />
        </View>
    )  
}

map_cat.js

import React from 'react';
import { StyleSheet, View, Text } from 'react-native';
import TenantListCat from '../shared/tableTenantCat';

export default function ScreenMapCategory({ navigation }) {
    return (
        <View style={styles.container}>
            <TenantListCat navigation={navigation} />
        </View>
    )  
}   

Я использую StackNavigator для этого приложения:

mapstack.js

import { createStackNavigator, createTopTabNavigator } from 'react-navigation-stack';
import Map from '../screens/map.js';
import React from 'react';
import CommonHeader from '../shared/header';
import TenantDetail from '../screens/tenant_detail';

const screens = {
    Map: {
        screen: Map,
        navigationOptions: ({ navigation }) => {
            return {
                headerTitle: () => <CommonHeader navigation={navigation} title="Directory" />
            }
        }
    },
    TenantDetail: {
        screen: TenantDetail,
        navigationOptions: ({ navigation }) => {
            return {
                //headerTitle: () => <CommonHeader navigation={navigation} title="News" />
                headerTitle: () => <Text>Directory</Text>
            }
        }
    }
}

const MapStack = createStackNavigator(screens);

export default MapStack;

Я не мог понять это - как передать объект навигации с родительского экрана на два экрана на вкладках для работы navigation.navigate ()?


person tg13    schedule 30.07.2020    source источник


Ответы (2)


Не похоже, что вы на самом деле используете интерактивную навигацию. Я бы реализовал это, тогда опора навигации будет передана на все ваши экраны, вы также сможете использовать хук useNavigation().

https://github.com/satya164/react-native-tab-view#react-navigation

https://reactnavigation.org/docs/tab-based-navigation

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

На странице github, в которой указан ваш вопрос: https://github.com/satya164/react-native-tab-view#renderscene-required

If you need to pass additional props, use a custom renderScene function:

const renderScene = ({ route }) => {
  switch (route.key) {
    case 'first':
      return <FirstRoute foo={this.props.foo} />;
    case 'second':
      return <SecondRoute />;
    default:
      return null;
  }
};

Что в вашем случае будет выглядеть так:

const renderScene = ({ route }) => {
  switch (route.key) {
    case 'first':
      return <ScreenMapAlpha navigation={navigation} />;
    case 'second':
      return <ScreenMapCategory navigation={navigation} />;
    default:
      return null;
  }
};
person GitGitBoom    schedule 30.07.2020
comment
Я использую StackNavigator, извините, забыл это указать. Я добавил свой код стека выше. Честно говоря, у меня проблемы с пониманием документации, я получил опыт работы с PHP и только пару недель изучаю react-native, а все еще новое и запутанное для меня. Попробую заставить работать хук useNavigation (), скрестив пальцы! - person tg13; 31.07.2020
comment
Не беспокойтесь, у вас, вероятно, возникнут проблемы, так как навигация по стеку, которую вы используете, является версией позади (версия 4), и вы, возможно, читаете документацию для версии 5. Если вы можете: я бы не использовал react-navigation-stack вместо этого, используйте @react-navigation/stack, обратите внимание, что реализация полностью отличается . Что касается вкладок: вы пытаетесь использовать модуль react-native-tab-view напрямую, вам нужно использовать одну из их оболочек, например эту reactnavigation.org/docs/material-top-tab-navigator (также версия 5) - person GitGitBoom; 31.07.2020
comment
Навигация по вкладкам в версии 4: reactnavigation.org/docs/4.x/tab- основанная навигация - person GitGitBoom; 31.07.2020
comment
Специальная функция renderScene сделала свое дело! Это то, что я пытался сделать все это время, мне нужно было передать объект навигации на два экрана в компоненте вкладки, я просто не знал правильного синтаксиса! То, как функции написаны в React / ES5, для меня совершенно новая концепция, так что это очень помогло. Спасибо!! - person tg13; 31.07.2020

создать функцию в const.js

import React from 'react';
import { useNavigation } from '@react-navigation/native'; 

export const withNavigation = (Component: any) => {
  return (props: any) => {
    const navigation = useNavigation();

    return <Component navigation={navigation} {...props} />;
  };
};

импорт и использование в вашем компоненте

import {
  withNavigation,
} from '../../helpers/functions';


export default  withNavigation(OrgWiseEvents)
person Rajesh Nasit    schedule 16.01.2021