React Native CLI抽屉布局失效及navigation类型错误求助
React Native CLI抽屉布局TypeScript类型错误解决
在React Native CLI(非Expo)环境中创建抽屉布局时,所有尝试的代码均无法正常运行,最终遇到类型错误提示:"Binding element 'navigation' implicitly has an 'any' type."
错误代码
import * as React from 'react'; import {View, Text, Button} from 'react-native'; import {NavigationContainer} from '@react-navigation/native'; import {createDrawerNavigator} from '@react-navigation/drawer'; import 'react-native-reanimated'; function HomeScreen({navigation}) { // 错误位置 return ( <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <Text>Home Screen</Text> <Button onPress={() => navigation.navigate('Notifications')} title="Go to notifications" /> </View> ); } function NotificationsScreen({navigation}) { // 错误位置 return ( <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <Text>Notifications Screen</Text> <Button onPress={() => navigation.goBack()} title="Go back home" /> </View> ); } const Drawer = createDrawerNavigator(); function MyDrawer() { return ( <Drawer.Navigator> <Drawer.Screen name="Home" component={HomeScreen} /> <Drawer.Screen name="Notifications" component={NotificationsScreen} /> </Drawer.Navigator> ); } export default function App() { return ( <NavigationContainer> <MyDrawer /> </NavigationContainer> ); }
package.json配置
{ "name": "MyApp", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "lint": "eslint .", "start": "react-native start", "test": "jest" }, "dependencies": { "@react-navigation/drawer": "^6.6.6", "react": "18.2.0", "react-native": "0.73.1", "react-native-reanimated": "^3.6.1", "react-native-safe-area-context": "^4.8.2", "react-native-screens": "^3.29.0" }, "devDependencies": { "@babel/core": "^7.20.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@react-native/babel-preset": "^0.73.18", "@react-native/eslint-config": "^0.73.1", "@react-native/metro-config": "^0.73.2", "@react-native/typescript-config": "^0.73.1", "@types/react": "^18.2.6", "@types/react-test-renderer": "^18.0.0", "babel-jest": "^29.6.3", "eslint": "^8.19.0", "jest": "^29.6.3", "prettier": "2.8.8", "react-test-renderer": "18.2.0", "typescript": "5.0.4" }, "engines": { "node": ">=18" } }
错误截图

解决方案
该错误源于TypeScript无法推断navigation参数的类型,默认视为any,而项目的TypeScript配置中可能开启了noImplicitAny规则(禁止隐式any类型)。解决方法是为navigation指定明确的类型:
步骤1:导入必要的类型
从@react-navigation/drawer和@react-navigation/native导入相关类型:
import { DrawerNavigationProp } from '@react-navigation/drawer'; import { useNavigation } from '@react-navigation/native';
步骤2:定义路由参数类型
声明抽屉导航的路由列表及参数:
// 定义所有抽屉页面的路由及参数(无参数则设为undefined) type RootDrawerParamList = { Home: undefined; Notifications: undefined; };
步骤3:为导航实例指定类型
使用useNavigation钩子获取导航实例并绑定类型,无需解构props:
function HomeScreen() { const navigation = useNavigation<DrawerNavigationProp<RootDrawerParamList, 'Home'>>(); // 组件内容保持不变 } function NotificationsScreen() { const navigation = useNavigation<DrawerNavigationProp<RootDrawerParamList, 'Notifications'>>(); // 组件内容保持不变 }
修改后的完整代码
import * as React from 'react'; import {View, Text, Button} from 'react-native'; import {NavigationContainer} from '@react-navigation/native'; import {createDrawerNavigator, DrawerNavigationProp} from '@react-navigation/drawer'; import {useNavigation} from '@react-navigation/native'; import 'react-native-reanimated'; type RootDrawerParamList = { Home: undefined; Notifications: undefined; }; function HomeScreen() { const navigation = useNavigation<DrawerNavigationProp<RootDrawerParamList, 'Home'>>(); return ( <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <Text>Home Screen</Text> <Button onPress={() => navigation.navigate('Notifications')} title="Go to notifications" /> </View> ); } function NotificationsScreen() { const navigation = useNavigation<DrawerNavigationProp<RootDrawerParamList, 'Notifications'>>(); return ( <View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}> <Text>Notifications Screen</Text> <Button onPress={() => navigation.goBack()} title="Go back home" /> </View> ); } const Drawer = createDrawerNavigator(); function MyDrawer() { return ( <Drawer.Navigator> <Drawer.Screen name="Home" component={HomeScreen} /> <Drawer.Screen name="Notifications" component={NotificationsScreen} /> </Drawer.Navigator> ); } export default function App() { return ( <NavigationContainer> <MyDrawer /> </NavigationContainer> ); }
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

