React Native Navigation (ver4.x) 无法在自定义 header 组件中获取道具。不断收到未定义的错误
React Native Navigation (ver4.x) unable to get props in custom header component. Keep getting undefined error
我的应用程序中有一个自定义 header,我试图让导航在单击 header 组件中的菜单项时打开抽屉。我已将导航和 header 文本作为道具传递给组件。然而,道具被返回为未定义。
这是我的header
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)/// 这会在加载组件时正确显示 header 文本。
但是,尝试在文本或视图中使用道具会引发未定义的错误。
点击 MaterialIcon 菜单图标出现错误:
Object{
“header文本”:未定义,
}
和
TypeError: undefined 不是 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);
如果有人感兴趣,这里是答案。我为嵌套导航器使用了 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',
},
});
我的应用程序中有一个自定义 header,我试图让导航在单击 header 组件中的菜单项时打开抽屉。我已将导航和 header 文本作为道具传递给组件。然而,道具被返回为未定义。
这是我的header
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)/// 这会在加载组件时正确显示 header 文本。 但是,尝试在文本或视图中使用道具会引发未定义的错误。
点击 MaterialIcon 菜单图标出现错误: Object{ “header文本”:未定义, }
和 TypeError: undefined 不是 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);
如果有人感兴趣,这里是答案。我为嵌套导航器使用了 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',
},
});