React Native之React Navigation导航器

最近在学习React Native,关于界面跳转这一块,文档上面写的并不清晰,自己也是研究了很久才搞清楚用法,这里记录下。

译注:从0.44版本开始,Navigator被从react native的核心组件库中剥离到了一个名为react-native-deprecated-custom-components的单独模块中。如果你需要继续使用Navigator,则需要先npm i facebookarchive/react-native-custom-components安装,然后从这个模块中import,即import { Navigator } from ‘react-native-deprecated-custom-components’.

今后社区主推的导航控件是react-navigation。

如果我们安装了yarn,那么只要使用yarn add react-navigation命令安装这个库就可以使用了。

如果我们在index.js入口中这么写的话

import { AppRegistry } from 'react-native';
import App from './App';
AppRegistry.registerComponent('ReactNativeSimple', () => App);

那么我们想在App组件中跳转到别的页面,那么我们就可以把navigation申明在App文件中然后导出,这里需要注意,default关键字不能申明在App类中了要申明在navigation导出的时候。
ps:navigation必须default申明原因我猜测因为default导出的类,在适用import导入的时候可以随便改写名字例如上面如果App是用default申明导出的那么上面代码import App from ‘./App’;我们可以随便写成import xxx from ‘./App’; 都可以,如果不适用default申明的话那么import 导入时候必须跟类名一模一样。 我们导出的navigation变量名叫啥系统也不知道,所以只能用default申明了。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from "react";
import {
  Platform,
  StyleSheet,
  Text,
  View,
  FlatList,
  Image,
  TouchableOpacity,
  TouchableHighlight,
  NativeModules,
  Alert
} from "react-native";
import DemoComponent from "./DemoComponent";
const instructions = Platform.select({
  ios: "Press Cmd+R to reload,\n" + "Cmd+D or shake for dev menu",
  android:
    "Double tap R on your keyboard to reload,\n" +
    "Shake or press menu button for dev menu"
});
import { StackNavigator } from "react-navigation";
export class App extends Component<Props> {
  static defaultProps = {
    textValue: "首页默认文本"
  };
  constructor(props) {
    super(props);
    this.state = {
      textValue: this.props.textValue
    };
  }
  testOnpress = () => {
    this.props.navigation.navigate("Profile", { name: "Jane" });
  };
  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={[{ key: "wubo" }]}
          renderItem={({ item }) => (
            <View style={styles.listItem}>
              <Image
                style={{ width: 30, height: 30 }}
                source={require("./icon.jpg")}
              />
              <Text onPress={this.testOnpress}>{this.state.textValue}</Text>
            </View>
          )}
        />
      </View>
    );
  }
}

const Navigate= StackNavigator({
  App: { screen: App },
  Profile: { screen: DemoComponent }
});

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#F5FCFF"
  },
  listItem: {
    flexDirection: "row",
    justifyContent: "center"
  },
  welcome: {
    fontSize: 20,
    textAlign: "center",
    margin: 10
  },
  instructions: {
    textAlign: "center",
    color: "#333333",
    marginBottom: 5
  }
});
export default AppN1;

我们在Navigation路由中申明了组件页面后,这个组件就具有了navigation props属性,我们就可以跳转到路由中申明的其他页面了。

但如果我们这样写的话主要有几点问题。 1. 我们的App没有用default申明,所以其他地方导出使用时必须是App类名不能更改这点上面已经提到。 2 . 如果我们把每个界面要跳转的页面都申明在这个组件类中,那么缺乏统一的管理显得非常混乱,这是不允许的。
所以上面方法虽然可以实现跳转但是强烈不建议这么做。

常规方式我们可以单独创建个js类单独管理所有要跳转的页面。
例如我创建个NavigationManager.js文件

import { StackNavigator } from "react-navigation";

import DemoComponent from "./DemoComponent";
import App from "./App";

const Navigate = StackNavigator(
  {
    App: { screen: App ,
      navigationOptions: {
        header: null
      }
    },
    Profile: { screen: DemoComponent }
  },
  {
    initialRouteName: "App"
  }
);

export default Navigate;

这里默认显示的页面是App组件
我们可以把所有需要跳转的页面都放在这个js申明的navigation中,然后默认导出,记住navigation一定要默认导出。

然后App组件代码我们修改成这样

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from "react";
import {
  Platform,
  StyleSheet,
  Text,
  View,
  FlatList,
  Image,
  TouchableOpacity,
  TouchableHighlight,
  NativeModules,
  Alert
} from "react-native";
const instructions = Platform.select({
  ios: "Press Cmd+R to reload,\n" + "Cmd+D or shake for dev menu",
  android:
    "Double tap R on your keyboard to reload,\n" +
    "Shake or press menu button for dev menu"
});
export default class App extends Component<Props> {
  static defaultProps = {
    textValue: "首页默认文本"
  };
  constructor(props) {
    super(props);
    this.state = {
      textValue: this.props.textValue
    };
  }
  testOnpress = () => {
    this.props.navigation.navigate("Profile", { name: "Jane" });
  };
  render() {
    return (
      <View style={styles.container}>
        <FlatList
          data={[{ key: "wubo" }]}
          renderItem={({ item }) => (
            <View style={styles.listItem}>
              <Image
                style={{ width: 30, height: 30 }}
                source={require("./icon.jpg")}
              />
              <Text onPress={this.testOnpress}>{this.state.textValue}</Text>
            </View>
          )}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#F5FCFF"
  },
  listItem: {
    flexDirection: "row",
    justifyContent: "center"
  },
  welcome: {
    fontSize: 20,
    textAlign: "center",
    margin: 10
  },
  instructions: {
    textAlign: "center",
    color: "#333333",
    marginBottom: 5
  }
});

我们在index.js中把入口从App改成Navigate.

import { AppRegistry } from 'react-native';
import Navigate from './NavigationManager';
AppRegistry.registerComponent('ReactNativeSimple', () => Navigate);

此时跟我们之前是一样的效果,但是把所有要跳转的页面管理在一起,代码就清爽很多,后期利于维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值