React Native路由(React-Navigation 5.X)之StackNavigator 篇【1】

1,439 阅读3分钟

安装

react-navigation 5.x 将各个导航部分独立出来了,安装需要一个一个去安装。

命令如下:(用npm安装也是可以的,例如:npm install @react-navigation/native)

// 安装react-navigation
yarn add @react-navigation/native
// 安装依赖库
yarn add react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
// 安装stack导航
yarn add @react-navigation/stack

StackNavigator的使用

StackNavigatiot:一次只渲染一个页面,并提供页面之间跳转的方法。 当打开一个新的页面时,它被放置在堆栈的顶部。

createStackNavigator函数:一个返回ScreenNavigator属性的对象。它们都是用于配置导航器的React组件。Navigator和Screen作为其子元素来定义路由的配置。

NavigationContainer是管理导航树并包含导航状态的组件。该组件必须包装所有导航器结构。通常,我们会在应用程序的根目录下渲染此组件,通常是从导出的组件App.js。但是我们也可以在自己指定的文件里做这些事,只要在根目录下index.js文件了把指向路由文件修改一下就可以了。

在刚学的时候都是在App.js里修改,之后运行直接就可以看到效果。copy代码时请把注释去掉运行

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

function HomePage() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home</Text>
    </View>
  );
}
function TwoScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Two</Text>
    </View>
  );
}
const Stack = createStackNavigator();

export default class App extends React.Component {
    render() {
      return (
        <NavigationContainer>
          // 可以在navigator 定义一些初始信息 initialRouteName为默认首页
          <Stack.Navigator initialRouteName="Home">
          	// screen 接受两个参数,name对应相应的component
            <Stack.Screen name="Home" component={HomePage} />
            // 可以为Screen定义一些options选项,例如title为呈现的标题或者通过`options={{ headerShown: false }}` 隐藏标题
            <Stack.Screen 
                name="Two" 
            	component={TwoScreen}
            	options={{ title: 'Overview' }} 
            />
          </Stack.Navigator>
        </NavigationContainer>
      );
    }
}

页面跳转传值

跳转方式有如下方式:

  1. navigation.navigate(name) 跳转到特定的路由,如果队列里有此路由,不会再队列里添加
  2. navigation.push(name) 跳转到特定路由,不会判断现有队列里是否存在此路由,直接添加
  3. navigation.pop() 出栈
  4. navigation.goBack() 返回
  5. navigation.popToTop() 跳转到队列里的第一个路由
  6. navigation.setParams() 在调用SetParams时,路由器将产生一个新的状态
  7. navigation.replace() 用新的route替换当前的route
  8. navigation.reset() 重置,将重置整个导航状态并将其替换为新的导航。
  9. navigation.dispatch() 向路由发送 action

在跳转时可以传递一些参数,供下个路由使用,下个屏幕以route.params的方式获取参数。请参考以下示例,HomeScreen跳转到DetailsScreen并传递了一些参数,DetailsScreen里通过route获取这些参数。在定义stack.screen时,也可以传递一些默认的参数,通过initialParams定义。

function HomePage({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Two"
        onPress={() => {
          /* 1. 跳转并传递参数 */
          navigation.navigate('Two', {
            itemId: 11111,
            otherParam: 'anything you want here',
          });
        }}
      />
    </View>
  );
}

function TwoScreen({ route, navigation }) {
  /* 2. 获取参数 */
  const { itemId } = route.params;
  const { otherParam } = route.params;
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Two Screen</Text>
      /* 使用参数 */
      <Text>itemId: {JSON.stringify(itemId)}</Text>
      <Text>otherParam: {JSON.stringify(otherParam)}</Text>
      <Button
        title="Go to Two... again"
        onPress={() =>
          navigation.push('Two', {
            itemId: Math.floor(Math.random() * 100),
          })
        }
      />
      <Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
      <Button title="Go back" onPress={() => navigation.goBack()} />
    </View>
  );
}

这章先讲这么多,下章讲StackNavigator的配置选项