接上篇文章,这篇我们来学习下react-native中如何使用导航

reactnavigation

安装

在React Native项目中安装所需的包:

npm install @react-navigation/native

npm install react-native-screens react-native-safe-area-context

npm install @react-navigation/native-stack

react-native-screens 包需要一个额外的配置步骤才能在Android设备上正常工作。编辑位于 android/app/src/main/java/<your package name>/ 下的 MainActivity.ktMainActivity.java 文件

添加如下代码

class MainActivity: ReactActivity() {
// ...
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(null)
}
// ...
}

App.tsx

import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
return (
<NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
);
}

然后运行npx react-native run-android 查看是否运行成功 如果报如下错误:

BUILD FAILED in 14s
error Failed to install the app. Command failed with exit code 1: gradlew.bat app:installDebug -PreactNativeDevServerPort=8081 FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':react-nat
uildCMakeDebug[armeabi-v7a]'. > Unable to delete file 'D:\react\rnApp\node_modules\react-native-screens\android\build\intermediates\cxx\Debug\422t2f3w\obj\armeabi-v7a' * Try: > Run with --stacktrace option to get the stack t
ith --info or --debug option to get more log output. > Run with --scan to get full insights. > Get more help at https://help.gradle.org. BUILD FAILED in 14s.
info Run CLI with --verbose flag for more details.

去对应目录把此目录直接删除即可 如上就是 ‘D:\react\rnApp\node_modules\react-native-screens\android\build\intermediates\cxx\Debug\422t2f3w\obj\armeabi-v7a

然后再重新运行即可

项目报红执行 npx eslint --fix .

还不行的话就cd到android目录然后执行 ./gradlew clean 再重新运行

此时手机上显示白屏 没有报错就说明成功了

App.tsx

// In App.js in a new project

import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}

const Stack = createNativeStackNavigator();

function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}

export default App;

此时会居中显示一个 Home Screen的页面,完整示例如下(基本路由的导航和传参)

// In App.js in a new project

import * as React from 'react';
import type {PropsWithChildren} from 'react';
import {View, Text, Button, StyleSheet, TouchableHighlight} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';

type SectionProps = PropsWithChildren<{
extraData?: string;
navigation: any;
route: any;
}>;

function HomeScreen({
extraData,
navigation,
route,
}: SectionProps): React.JSX.Element {
const [postParams, setParams] = React.useState('我是默认值');

React.useEffect(() => {
if (route.params?.post) {
console.log(route.params.post);
setParams(route.params.post);
}
}, [route.params?.post]);
return (
<View
style={{
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>Home Screen{extraData}</Text>
<Text>{postParams}</Text>
<Button
title="Go to Details"
onPress={() =>
/* 1. 使用参数传参到Details页面 */
navigation.navigate('Details', {
itemId: Math.floor(Math.random() * 100),
otherParam: 'anything you want here',
})
}
/>
</View>
);
}

function DetailsScreen({navigation, route}: SectionProps): React.JSX.Element {
// 样式
const styles = StyleSheet.create({
ButtonBack: {
marginTop: 20,
},
button: {
backgroundColor: '#007bff', // 按钮背景颜色
padding: 10,
borderRadius: 5,
marginTop: 20,
},
text: {
color: '#ffffff', // 文字颜色
textAlign: 'center',
},
});

/* 2. 接受Home传的参数 */
const {itemId, otherParam} = route.params;

return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<Text>Details Screen0</Text>
<Text>itemId: {JSON.stringify(itemId)}</Text>
<Text>otherParam: {JSON.stringify(otherParam)}</Text>
<View style={[styles.ButtonBack]}>
<Button
title="Go to Home"
onPress={() => navigation.navigate('Home')}
/>
</View>
<View style={[styles.ButtonBack]}>
<Button
color={'orange'}
title="Go back"
onPress={() => navigation.goBack()}
/>
</View>
{/* 自定义按钮 */}
<TouchableHighlight
style={styles.button}
underlayColor={'#0069d9'}
onPress={() => alert('按钮被点击了')}>
<Text style={styles.text}>点击我(自定义按钮)</Text>
</TouchableHighlight>
<View style={[styles.ButtonBack]}>
{/* 3.更新传过来的参数值 */}
<Button
title="更新参数"
onPress={() =>
navigation.setParams({
otherParam: 'someText',
})
}
/>
</View>
<View style={[styles.ButtonBack]}>
{/* 4.回传参数 把Home的参数回传过去 */}
<Button
title="回传参数"
onPress={() => {
// Pass and merge params back to home screen
navigation.navigate({
name: 'Home',
params: {post: '我是详情页回传的参数'},
merge: true,
});
}}
/>
</View>
</View>
);
}

const Stack = createNativeStackNavigator();

function App() {
const [someData] = React.useState('some data');
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
options={{
title: 'Home',
headerStyle: {
backgroundColor: '#f1f1f1', //顶部标题背景
},
headerTintColor: '#000',
headerShadowVisible: false, //是否显示阴影
headerTitleAlign: 'center', //居中还是left
headerTitleStyle: {
fontWeight: 'bold',
color: '#000',
},
headerRight: () => (
<Button
onPress={() => alert('This is a button!')}
title="Info"
color="blue"
/>
),
}}>
{props => <HomeScreen {...props} extraData={someData} />}
</Stack.Screen>
<Stack.Screen
name="Details"
component={DetailsScreen}
// 在标题中使用params
options={({route}: any) => ({
title: 'Details-' + route?.params?.itemId,
headerStyle: {
backgroundColor: '#fff', //顶部标题背景
},
})}
// 默认参数如果没有传默认值
initialParams={{itemId: 42}}
/>
</Stack.Navigator>
</NavigationContainer>
);
}

export default App;