首页 > 解决方案 > React Native Navigation (ver4.x) 无法在自定义标头组件中获取道具。不断收到未定义的错误

问题描述

我的应用程序中有一个自定义标题,当单击标题组件中的菜单项时,我试图让导航打开抽屉。我已将导航和标题文本作为道具传递给组件。然而,道具被返回为未定义。

这是我的标题

import React from 'react';
import {View, StyleSheet, Text, Image, Alert, TouchableOpacity } from 'react-native';
import Colors from '../constants/Colors';
import { MaterialIcons } from '@expo/vector-icons';


const Header = ({navigation, headerText}) => {

 
    const openMenu = () => {
        console.log({headerText}) **/// this prints Object {  "headerText": undefined,}**
      navigation.openDrawer() **/// this also throws an undefined error**
    }

    console.log(headerText)**/// this displays the headerText correct on loading**

    return (
        <View style={styles.header} >
            <MaterialIcons onPress={openMenu} name='menu' size={30} style={styles.icon} />
            <Text style={styles.logo}>My Home Page Header</Text>
        </View>
    );
};

const styles = StyleSheet.create({
    header: {
        paddingTop: 20,
        width: '100%',
        height: '10%',
        flexDirection: 'row',
    },
    logo: {
        height: '100%',
        width: '90%',
        fontFamily: 'pacifico-regular', 
        fontSize: 28,
        paddingTop: 20,
        paddingLeft: 20,
    },
    icon: {
        marginTop:30,
        paddingLeft: 10,
    },
});

export default Header;

console.log(headerText)/// 这会在加载组件时正确显示标题文本。但是,尝试在 Text 或 View 中使用道具会引发未定义的错误。

单击 MaterialIcon 菜单图标会出现错误: Object { "headerText": undefined, }

TypeError: undefined is not an object (评估 'navigation.openDrawer')

这是 homestack.js

import { createStackNavigator } from 'react-navigation-stack';
import NewFeaturedRecipes from '../screens/NewFeaturedRecipes';
import NewRecipeDetails from '../screens/NewRecipeDetails';
import Header from '../shared/Header';
import React from 'react';
import {navigation} from 'react-navigation'

// const navigation = navigation;

const screens  = {
    NewFeaturedRecipes: {
        screen: NewFeaturedRecipes,
        navigationOptions: ({navigation}) => {
            return {
                headerTitle: () => <Header navigation={navigation}
                  headerText='Testting headertext from hoomestack' />
            }
        }
    },
    NewRecipeDetails: {
        screen: NewRecipeDetails,
        navigationOptions:  {
            title: 'Recipe Details',
        }
    },
}

const HomeStack = createStackNavigator(screens, {
    defaultNavigationOptions: {
        headerStyle: {
            height: 20,
        },
    }
});

export default (HomeStack);

标签: reactjsreact-nativereact-navigationreact-navigation-drawer

解决方案


如果有人感兴趣,这里的答案。我已经将 React Navigation 5.x 用于嵌套导航器,并且可以从 Header 组件的菜单中调用 openDrawer()。

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View, Button, DrawerLayoutAndroid } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import {createDrawerNavigator} from '@react-navigation/drawer';
import { MaterialIcons } from '@expo/vector-icons';


const Header = ({ headerText }) => {
  const navigation = useNavigation()
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', flexDirection: 'row' }}>
      <MaterialIcons onPress={()=> navigation.openDrawer()} name='menu' size={30} style={styles.icon} />
      <Text>Header Text = {headerText}</Text>
    </View>
  )
}

const HomeScreen = ({ navigation }) => {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button onPress={() => navigation.navigate('Details')} title='Goto Details Screen' />
    </View>
  )
}

const DetailScreen = ({ navigation }) => {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Detail Screen</Text>
      <Button onPress={() => navigation.navigate('Home')} title='Goto Home Screen' />
    </View>
  )
}

const HomeStack = () => {
  return (
    <Stack.Navigator>
      <Stack.Screen
        name='Home'
        component={HomeScreen}
        options={{
          headerTitle: props => <Header headerText='Text from App' />
        }}
      />
      <Stack.Screen name='Details' component={DetailScreen} options={{
          headerTitle: props => <Header headerText='Text from Details' />
        }}
        />
    </Stack.Navigator>
  )
}

function NotificationsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center', flexDirection:'column' }}>
      <Text>Notifications Screen</Text>
      <Button onPress={() => navigation.goBack()} title="Go back home" />
    </View>
  );
}

const Stack = createStackNavigator()
const Drawer = createDrawerNavigator()

const App = () => {
  return (
    <NavigationContainer>
      <Drawer.Navigator initialRouteName='Home'>
        <Drawer.Screen name='Home' component={HomeStack}/>
        <Drawer.Screen name='Notifications' component={NotificationsScreen}/>
      </Drawer.Navigator>
    </NavigationContainer>
  )
}

export default App

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

推荐阅读