05三方库--001--react-navigation

2020-10-27  本文已影响0人  修_远

[TOC]

https://reactnavigation.org

导入react-navigation

  1. 安装基础库
npm install @react-navigation/native
  1. 安装依赖库
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
  1. iOS项目安装依赖库
npx pod-install ios
  1. 引用库,在 index.js 和 app.js 等入口文件中
import 'react-native-gesture-handler';
import 'react-native-gesture-handler';
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
  );
}
  1. 安装导航栏管理栈
npm install @react-navigation/stack
  1. 例子:在项目中引用库
// 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 { createStackNavigator } from '@react-navigation/stack';

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

const Stack = createStackNavigator();

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

export default App;

到这里,基本上已经配置好导航栏的环境,最后一个例子也提供了如何使用这个库。后面会讲解这个库的常用API的使用方式。

使用react-navigation

定义一个导航栏的视图

定义一个导航栏控制栈

const Stack = createStackNavigator();

1、栈里只有一个视图

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

2、栈里有多个视图

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

3、其他定义格式

function App() {
  return (
    <NavigationContainer>
      <Stack.Screen
        name="Home"
        component={HomeScreen}
        options={{ title: 'Overview' }}
      />
    </NavigationContainer>
  );
}

推出一个新的视图

按照上面的第二种方式定义导航栏

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

1、navigation.navigate('Details'):以一个新的导航栏控制栈推出视图

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Details"
        onPress={() => navigation.navigate('Details')}
      />
    </View>
  );
}

2、navigation.push('Details'):从当前栈推出一个新的视图

function DetailsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
      <Button
        title="Go to Details... again"
        onPress={() => navigation.push('Details')}
      />
    </View>
  );
}

3、两者区别

navigation.navigate('Details')

navigation.push('Details')

返回上一个界面

1、返回指定界面:navigation.navigate("Home")

<Button title="Go to Home" onPress={() => navigation.navigate("Home")} />

2、返回上一个界面:navigation.goBack()

<Button title="Go back" onPress={() => navigation.goBack()} />

3、返回第一个界面:navigation.popToTop()

<Button title="Go back to first screen in stack" onPress={() => navigation.popToTop()} />

导航栏的参数传递

正向传递

1、navigation.navigate(obj)使用示例

navigation.navigate('Details', {
                itemId: 886,
                otherParam: '传递任何你想传递的',
})

2、navigation.push(obj)使用示例

navigation.push('Details', {
            itemId: Math.floor(Math.random() * 100),
})

从上面两个例子可以看出来,他们的传递方式其实是一模一样的:

3、获取参数传递内容

参数传过来了,只有准确拿到传过来的参数并且被解析了才是我们想要的结果

反向传递

结合 返回上一个界面 这节里面的内容,其实我们可以推断出反向传递的实现过程。

function HomeScreen({ navigation, route }) {
  React.useEffect(() => {
    if (route.params?.post) {
      // Post updated, do something with `route.params.post`
      // For example, send the post to the server
    }
  }, [route.params?.post]);

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button
        title="Create post"
        onPress={() => navigation.navigate('CreatePost')}
      />
      <Text style={{ margin: 10 }}>Post: {route.params?.post}</Text>
    </View>
  );
}

function CreatePostScreen({ navigation, route }) {
  const [postText, setPostText] = React.useState('');

  return (
    <>
      <TextInput
        multiline
        placeholder="What's on your mind?"
        style={{ height: 200, padding: 10, backgroundColor: 'white' }}
        value={postText}
        onChangeText={setPostText}
      />
      <Button
        title="Done"
        onPress={() => {
          // Pass params back to home screen
          navigation.navigate('Home', { post: postText });
        }}
      />
    </>
  );
}

更新参数 & 初始化参数

1、初始化参数 initialParams

如果没有传特定的值,那么就会使用初始化参数里面的数值。例如下面例子中的 itemId: 42,如果obj的参数传递中并没有指定 itemId,那么就会使用这个初始值 42

<Stack.Screen
  name="Details"
  component={DetailsScreen}
  initialParams={{ itemId: 42 }}
/>

2、更新参数 setParams

这个方法可以可以更新 route.params 中的参数,类似于组件中的 setState 方法,主要用于刷新当前页面中 setState。使用例子如下:

function ProfileScreen({ navigation: { setParams } }) {
  render() {
    return (
      <Button
        onPress={() =>
          setParams({
            friends:
              route.params.friends[0] === 'Brent'
                ? ['Wojciech', 'Szymon', 'Jakub']
                : ['Brent', 'Satya', 'Michaś'],
            title:
              route.params.title === "Brent's Profile"
                ? "Lucy's Profile"
                : "Brent's Profile",
          })
        }
        title="Swap title and friends"
      />
    );
  }
}
上一篇 下一篇

猜你喜欢

热点阅读