React Native Stack Navigator 不接受屏幕作为组件道具中的道具
React Native Stack Navigator does not accepts a Screen as a prop in component prop
我正在为这个 React Native 项目使用 expo v4.9.1。
我正在按照这个 Document 实现堆栈导航器。它是这样的
App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Provider } from 'react-redux'
import HomeScreen from './screens/HomeScreen';
import { store } from './store';
import { SafeAreaProvider } from 'react-native-safe-area-context'
import 'react-native-gesture-handler';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import MapScreen from './screens/MapScreen';
import 'react-native-gesture-handler';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import { GOOGLE_MAPS_APIKEY } from '@env'
export default function App() {
const Stack = createStackNavigator();
return (
<Provider store={store}>
<NavigationContainer>
<SafeAreaProvider>
<Stack.Navigator>
<Stack.Screen name='HomeScreen' component={HomeScreen} options={{headerShown: false}}/>
<Stack.Screen name='MapScreen' component={MapScreen} options={{headerShown: false}}/>
<GooglePlacesAutocomplete
placeholder='Where From?'
nearbyPlacesAPI='GooglePlacesSearch'
debounce={300}
/>
</Stack.Navigator>
</SafeAreaProvider>
</NavigationContainer>
</Provider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
从 HomeScreen
访问 MapScreen
HomeScreen.js
import React from 'react'
import { StyleSheet, Text, View, SafeAreaView, Image } from 'react-native'
import tw from 'tailwind-react-native-classnames'
import NavOptions from '../components/NavOptions'
const HomeScreen = () => {
return (
<SafeAreaView style={tw`bg-white h-full`}>
<View style={tw`p-5`}>
<Image
style={{
width: 100,
height:100,
resizeMode: 'contain',
}}
source={{
uri: 'https://links.papareact.com/gzs'
}}
/>
<NavOptions />
</View>
</SafeAreaView>
)
}
export default HomeScreen
const styles = StyleSheet.create({
text: {
color: 'blue',
}
})
NavOptions.js
import { useNavigation } from '@react-navigation/native';
import React from 'react'
import { FlatList, Image, Text, TouchableOpacity, View } from 'react-native'
import { Icon } from 'react-native-elements/dist/icons/Icon';
import tw from 'tailwind-react-native-classnames'
const data =[
{
id: '123',
title: 'Get a ride',
image: 'https://links.papareact.com/3pn',
screen: 'MapScreen',
},
{
id: '456',
title: 'Order food',
image: 'https://links.papareact.com/28w',
screen: 'EatScreen',
}
];
const NavOptions = () => {
const navigation = useNavigation();
return (
<FlatList
data={data}
horizontal
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<TouchableOpacity
onPress={() => navigation.navigate(item.screen)}
style={tw`p-2 pl-6 pb-8 pt-4 bg-gray-200 m-2 w-40 rounded-xl`}
>
<View>
<Image
style={{ width: 120, height: 120, resizeMode: 'contain' }}
source={{uri: item.image}}
/>
<Text style={tw`mt-2 text-lg font-semibold`}>{item.title}</Text>
<Icon
style={tw`p-2 bg-black rounded-full w-10 mt-4`}
type='antdesign'
name='arrowright'
color='white'
/>
</View>
</TouchableOpacity>
)}
/>
)
}
export default NavOptions
我用过useNavigation()
钩子。但是我收到错误
A navigator can only contain 'Screen' components as its direct children (found 'undefined'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.
This error is located at:
in StackNavigator (at App.js:23)
in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
in SafeAreaProvider (at App.js:22)
in EnsureSingleNavigator (at BaseNavigationContainer.tsx:409)
in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:91)
in ThemeProvider (at NavigationContainer.tsx:90)
in ForwardRef(NavigationContainer) (at App.js:21)
in Provider (at App.js:20)
in App (created by ExpoRoot)
in ExpoRoot (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:171:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/expo-error-recovery/build/ErrorRecovery.fx.js:12:21 in ErrorUtils.setGlobalHandler$argument_0
at [native code]:null in flushedQueue
at [native code]:null in invokeCallbackAndReturnFlushedQueue
针对 Whosebug thread and GitHub issues thread 中完全相同的问题提供了一些解决方案。 None 其中对我有用,似乎没有关于此错误如何发生的确切解释。我也在使用 node v14.16.0 和 npm v7.20.1
所以我深入研究了 react-navigation
的源代码并为您找到了答案。根据 https://github.com/react-navigation/react-navigation/blob/42a875212c5071b12e92eaf159ef488365413ab8/packages/core/src/useNavigationBuilder.tsx <Stack.Navigator>
的设计使其 children 仅为 Screen
个元素:
if (React.isValidElement(child)) {
if (child.type === Screen) {
// We can only extract the config from `Screen` elements
// If something else was rendered, it's probably a bug
acc.push([...
这就是为什么将 <GooglePlacesAutocomplete>
放在 <Stack.Navigator>
中你得到了一个错误
throw new Error(
`A navigator can only contain 'Screen' as its direct children ...
);
我正在为这个 React Native 项目使用 expo v4.9.1。 我正在按照这个 Document 实现堆栈导航器。它是这样的 App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Provider } from 'react-redux'
import HomeScreen from './screens/HomeScreen';
import { store } from './store';
import { SafeAreaProvider } from 'react-native-safe-area-context'
import 'react-native-gesture-handler';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import MapScreen from './screens/MapScreen';
import 'react-native-gesture-handler';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
import { GOOGLE_MAPS_APIKEY } from '@env'
export default function App() {
const Stack = createStackNavigator();
return (
<Provider store={store}>
<NavigationContainer>
<SafeAreaProvider>
<Stack.Navigator>
<Stack.Screen name='HomeScreen' component={HomeScreen} options={{headerShown: false}}/>
<Stack.Screen name='MapScreen' component={MapScreen} options={{headerShown: false}}/>
<GooglePlacesAutocomplete
placeholder='Where From?'
nearbyPlacesAPI='GooglePlacesSearch'
debounce={300}
/>
</Stack.Navigator>
</SafeAreaProvider>
</NavigationContainer>
</Provider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
从 HomeScreen
访问 MapScreen
HomeScreen.js
import React from 'react'
import { StyleSheet, Text, View, SafeAreaView, Image } from 'react-native'
import tw from 'tailwind-react-native-classnames'
import NavOptions from '../components/NavOptions'
const HomeScreen = () => {
return (
<SafeAreaView style={tw`bg-white h-full`}>
<View style={tw`p-5`}>
<Image
style={{
width: 100,
height:100,
resizeMode: 'contain',
}}
source={{
uri: 'https://links.papareact.com/gzs'
}}
/>
<NavOptions />
</View>
</SafeAreaView>
)
}
export default HomeScreen
const styles = StyleSheet.create({
text: {
color: 'blue',
}
})
NavOptions.js
import { useNavigation } from '@react-navigation/native';
import React from 'react'
import { FlatList, Image, Text, TouchableOpacity, View } from 'react-native'
import { Icon } from 'react-native-elements/dist/icons/Icon';
import tw from 'tailwind-react-native-classnames'
const data =[
{
id: '123',
title: 'Get a ride',
image: 'https://links.papareact.com/3pn',
screen: 'MapScreen',
},
{
id: '456',
title: 'Order food',
image: 'https://links.papareact.com/28w',
screen: 'EatScreen',
}
];
const NavOptions = () => {
const navigation = useNavigation();
return (
<FlatList
data={data}
horizontal
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<TouchableOpacity
onPress={() => navigation.navigate(item.screen)}
style={tw`p-2 pl-6 pb-8 pt-4 bg-gray-200 m-2 w-40 rounded-xl`}
>
<View>
<Image
style={{ width: 120, height: 120, resizeMode: 'contain' }}
source={{uri: item.image}}
/>
<Text style={tw`mt-2 text-lg font-semibold`}>{item.title}</Text>
<Icon
style={tw`p-2 bg-black rounded-full w-10 mt-4`}
type='antdesign'
name='arrowright'
color='white'
/>
</View>
</TouchableOpacity>
)}
/>
)
}
export default NavOptions
我用过useNavigation()
钩子。但是我收到错误
A navigator can only contain 'Screen' components as its direct children (found 'undefined'). To render this component in the navigator, pass it in the 'component' prop to 'Screen'.
This error is located at:
in StackNavigator (at App.js:23)
in RNCSafeAreaProvider (at SafeAreaContext.tsx:76)
in SafeAreaProvider (at App.js:22)
in EnsureSingleNavigator (at BaseNavigationContainer.tsx:409)
in ForwardRef(BaseNavigationContainer) (at NavigationContainer.tsx:91)
in ThemeProvider (at NavigationContainer.tsx:90)
in ForwardRef(NavigationContainer) (at App.js:21)
in Provider (at App.js:20)
in App (created by ExpoRoot)
in ExpoRoot (at renderApplication.js:45)
in RCTView (at View.js:34)
in View (at AppContainer.js:106)
in RCTView (at View.js:34)
in View (at AppContainer.js:132)
in AppContainer (at renderApplication.js:39)
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:171:19 in handleException
at node_modules/react-native/Libraries/Core/setUpErrorHandling.js:24:6 in handleError
at node_modules/expo-error-recovery/build/ErrorRecovery.fx.js:12:21 in ErrorUtils.setGlobalHandler$argument_0
at [native code]:null in flushedQueue
at [native code]:null in invokeCallbackAndReturnFlushedQueue
针对 Whosebug thread and GitHub issues thread 中完全相同的问题提供了一些解决方案。 None 其中对我有用,似乎没有关于此错误如何发生的确切解释。我也在使用 node v14.16.0 和 npm v7.20.1
所以我深入研究了 react-navigation
的源代码并为您找到了答案。根据 https://github.com/react-navigation/react-navigation/blob/42a875212c5071b12e92eaf159ef488365413ab8/packages/core/src/useNavigationBuilder.tsx <Stack.Navigator>
的设计使其 children 仅为 Screen
个元素:
if (React.isValidElement(child)) {
if (child.type === Screen) {
// We can only extract the config from `Screen` elements
// If something else was rendered, it's probably a bug
acc.push([...
这就是为什么将 <GooglePlacesAutocomplete>
放在 <Stack.Navigator>
中你得到了一个错误
throw new Error(
`A navigator can only contain 'Screen' as its direct children ...
);