react-native入门教程

React Native是什么, 能解决什么问题 
 
官网介绍: Build Native Mobile Apps using JavaScript and React.
 
React Native 是一款JavaScript 框架, 如何使用其开发真正原生、可渲染的 iOS 和 Android 移动应用。
 

1、React Native是什么, 能解决什么问题 

2、对比其他技术理解为什么使用React Native

3、React Native的环境搭建

4、React Native 的组件,样式

5、一些问题

* 文档地址
 
1.React Native是什么, 能解决什么问题 
 
React  针对HTML(网页前端DOM渲染)
ReactNative  是基于React 的一种封装,比专用于移动端的界面渲染。ios ,Android等原生的组件渲染。
都是通过js实现对虚拟DOM驱动界面完成View渲染(重点:ReactNative 只针对MVC中的V层渲染,是一个界面的相关框架)
 
* 官网介绍: Build Native Mobile Apps using JavaScript and React.
React Native lets you build mobile apps using only JavaScript. It uses the same design as React, letting you compose a rich mobile UI from declarative components.
> 翻译: React Native通过JavaScript语言 和 React风格 构建原生移动应用, 通过声明各种组件创建出一个丰富多彩的移动UI界面.
 
react-native依赖库
 
React Native着力于提高多平台开发的开发效率 —— 仅需学习一次,编写任何平台。(Learn once, write anywhere)
* 创建的应用内皆是原生的自定义组件. 生成运行的代码仍然是Java或Objective-C
* 不用在编译应用上浪费时间, 代码修改完可以立即看到效果  
 
解决公司开发人员不足的问题: Android、ios、winphone等,后期会推出更多平台支持。
为公司节省开支。
代码动态更新
 
阿里的天猫pad,美团的app  网易有钱iOS版本的『理财』模块等等。
 
2.对比其他技术理解为什么使用React Native
 
 跨平台开发框架
> (例如 PhoneGap,RubyMotion,Bootstrap)基于一个WebView, 使用 HTML,CSS 和 JavaScript 来将 web 的内容和体验搬到本地. 渲染速度比原生缓慢, 动画效率低.这种方式开发的 app 一般被称为 Hybrid app
 
* Xamarin框架, C#语言跨平台开发.优点是界面渲染高效. 缺点是API是由 Xamarin 所决定的,一旦 iOS 或Android平台推出了新的SDK, 必须等Xamarin 升级才能使用新的sdk.
 
* NativeScript框架, 通过反射得到所有平台 API,进行预编译,将这些 API 注入JavaScript运行环境,最后在Javascript 调用后拦截这个调用,并运行 native 代码。这个是一个小公司维护。
 
 
3.React Native的环境搭建

1)搭建JAVA开发环境

根据操作系统分为x86或x64位的,下载jdk1.8以上的版本,

本机安装时的java版本:jdk-8u45-windows-x64.exe

配置JAVA的环境变量
 
  1. JAVA_HOME = C:\Program Files\Java\jdk1.8.0_45   。。。。。。。。、、
 

2)安装Android Studio

本机安装时的Android Studio版本:androidstudio2.1.1


增加Android SDK的环境变量配置

http://developer.android.com/sdk/index.html SDK下载地址

  1. ANDROID_HOME = D:\Android\sdk  
  2. path 增加 ;%ANDROID_HOME%;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools; 
    需要下载SDKAndroid 6.0(API23),
    Android SDK Build-tools 23.0.1    
 

3)安装NodeJS开发环境

安装流程参考:http://blog.csdn.net/itpinpai/article/details/48103845
 

4)安装Git版本控制

可选择安装,但建议安装,之后用的多。

安装流程参考:http://blog.csdn.net/itpinpai/article/details/48105445

 

 

5)安装虚拟机

本机安装版本:2.6.0

这个软件需要在官网上注册一个账号,先注册才能下载,官网地址:www.genymotion.com/


 

6)安装React-native-cli

    npm install -g react-native-cli  
    npm是一个node包管理和分发工具
    npm 命令格式
    npm install moduleNames:安装Node模块
    安装的时候,你会发现,安装速度巨慢,这是因为默认的npm仓库在国外,我们可以修改成国内的淘宝地址。
 
配置npm镜像 (或可直接FQ上网)
  • npm config set registry https://registry.npm.taobao.org
  • npm config set disturl https://npm.taobao.org/dist

如果你安装的模块依赖了 C++ 模块, 需要编译, 肯定会通过 node-gyp 来编译, node-gyp 在第一次编译的时候, 需要依赖 node 源代码, 于是又会去 node dist 下载, 于是大家又会吐槽, 怎么 npm 安装这么慢…

这就是为何要设置disturl

或者直接打开指定的配置文件修改。
 

7)第一个React Native程序

初始化项目
 
    react-native init training

测试是否创建成功

cd training

react-native start
 

运行 android app

cd training

react-native run-android  
注意:项目运行到手机后, 界面没有内容或显示为红色, 说明手机或模拟器没有和电脑在同一个网段, 无法访问到JS的服务。

解决方法:在手机端按菜单键 -> Dev Settings -> Debug server host&port for device -> 在弹出的框中输入pc的ip和端口号, 如10.0.3.2:8081 确认后回到界面, 点击 菜单 -> Reload 重新加载

了解代码结构

  1. import模块

    类似于java的import和c++的#include,用于引入其他模块

    import React, { Component } from 'react';
    // 从react-native中批量导入组件
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View
    } from 'react-native';
    
  2. 视图组件声明模块

    界面的入口, render函数用于渲染视图, return返回的即为界面显示的内容.其语法规范是JSX

    class Training extends Component {
      render() {
        return (
          <View >...</View>
        );
      }
    }
    
  3. 样式配置模块.

    此模块配置了视图显示的样式效果.在视图组件模板中的使用方式 给视图添加类似属性style={styles.container}即可

    const styles = StyleSheet.create({
      container: {
        ...
      },
      welcome: {
        ...
      },
      instructions: {
        ...
      },
    });
    
  4. 注册应用的入口.

    第一个'ItcastDemo'是项目名称, 第二个ItcastDemo是视图组件名称. 两个名称可以不同。此入口必须要配置。

    AppRegistry.registerComponent('training', () => Training);

React Native的特点及需要掌握的知识

  • 特点:
    1. 界面展示(Just the UI), 作为MVC的View层
    2. 虚拟DOM (Virtual DOM), 特性,在内存中高效更新视图,实现差异化更新
    3. 数据流 (Data Flow), 单向数据流. 渲染顺序从父节点传递到子节点,如果顶层组件的某个prop改变了,React会递归的向下便利整棵组件树,重新渲染所有使用这个属性的组件。
  • 需要的知识

    1. JSX语法(全程JavaScript XML) ,每一个XML标签都会被JSX转换工具转换成纯Javascript代码
    2. ES6语法知识.React Native从0.18之后,新建项目默认已经采用了ES6语法.可以参考阮一峰的ES6教程,非常详细。
    3. css, div, js基础

            
4、React Native 的组件,样式
 

1)图片组件Image

  • 本地图片引用

    class Training extends Component {
      render() {
        return (
            <Image
                style={styles.pic}
                source={require('./img/164854172.jpg')}></Image>
        );
      }
    }
    
  • 网络图片的引用

    class Training extends Component {
      render() {
        return (
            <Image
                resizeMode='contain'
                style={styles.pic}
                source={{uri:'https://www.baidu.com/img/bd_logo1.png'}}></Image>
        );
      }
    }

2)组件的嵌套

  • 组件的嵌套
  • class Training extends Component {
      render() {
        return (
            <View style={styles.container}>
              <Image
                  resizeMode='contain'
                  style={styles.pic}
                  source={{uri:'https://www.baidu.com/img/bd_logo1.png'}}></Image>
              <Tip />
            </View>
        );
      }
    }
    //自定义一个组件
    class Tip extends Component {
      render() {
        return (
            <View>
              <Text style={{color:'green'}}>我是react-native,我用来跨平台!</Text>
              < Tip2 />
            </View>
    
        );
      }
    }
    //自定义一个子组件
    class Tip2 extends Component {
      render() {
        return (
            <Text style={{color:'red'}}>我是孩子组件!</Text>
        );
      }
    }

3)组件的属性Props

  • 引入组件属性

    class MyProp extends Component {
      //初始化props默认值
      static defaultProps = {
        name:'我是默认值',
      }
      //props验证
      static propTypes = {
        name:React.PropTypes.string.isRequired
      }
    
    
      render() {
        return (
            <Text style={{color:'red'}}>Hello,{this.props.name}!</Text>
        );
      }
    }
    class MyProps extends Component {
      render() {
        return (
            <View style={styles.container}>
              <MyProp/>
              <MyProp name='牛逼' />
            </View>
    
        );
      }
    }

4)组件的状态State

  • 引入组件状态

    class MyState extends Component {
      constructor(props){
        super(props);
        this.state = {
          showText:true,
        };
        //每一秒中对showText进行取反操作。
        setInterval(()=>{
          this.setState({
            showText:!this.state.showText
          });
        },1000);
      }
      render() {
        let display = this.state.showText?this.props.text:'';
        return (
            <Text>{display}</Text>
        );
      }
    }
    class MyStates extends Component {
      render() {
        return (
            <View style={styles.container}>
              <MyState text='这是啥玩意' />
            </View>
        );
      }
    }

5)文本输入TextInpput组件

  • 引入文本输入

    /**
     * 练习文本输入
     */
    class MyTextInput extends Component{
      constructor(props){
        super(props);
        this.state = {
          text:''
        };
      }
      render(){
        return(
            <View style={{padding:10}}>
              <TextInput
                  style={{height:40}}
                  placeholder='请输入翻译文字'
                  onChangeText={(text)=>this.setState({text})}/>
              <Text style={{padding:10,fontSize:42}}>
                {this.state.text.split(' ').map((word)=>word && '#')}
              </Text>
            </View>
        );
      }
    }

6)动画组件Animated

  • 引入动画

    /**
     * 动画效果
     */
    class MyAnimation extends Component{
        constructor(props:any){
            super(props);
            this.state = {
                bounceValue:new Animated.Value(0),
            };
        }
        render():ReactElement{
            return (
                <Animated.Image
                    source={{uri:'https://www.baidu.com/img/bd_logo1.png'}}
                    resizeMode='contain'
                    style={{
                        flex:1,
                        transform:[
                            {scale:this.state.bounceValue},
                        ]
                    }}>
                </Animated.Image>
            );
        }
        componentDidMount(){
            this.state.bounceValue.setValue(1.5);
                Animated.spring(
                    this.state.bounceValue,
                    {
                        toValue:0.8,
                        friction:1,
                        tension:100
                    }
                ).start();
        }
    }

7)完整综合练习实例

  • 网络请求,样式,列表

    var REQUEST_URL = 'https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json';
    class SimpleList extends Component{
    
      constructor(props){
        super(props);
        this.state = {
          movies:null,
        };
        /*this.fetchData = this.fetchData.bind(this);源代码中是由这一句的,但是去除也没有问题。*/
      }
      componentDidMount(){
        this.fetchData();
      }
      fetchData(){
        //在es6中,只要涉及到this指正,都需要使用bind或者=>来绑this引用
        fetch(REQUEST_URL)
            .then((respose) => respose.json())
            .then(function(resposeData){
              this.setState({
                movies:resposeData.movies,
              });
            }.bind(this)).done();
      }
    
      render(){
        if(!this.state.movies){
          return this.renderLoadingView();
        }
        var movie = this.state.movies[1];
        return this.renderMovie(movie);
      }
      renderLoadingView(){
        return (
            <View style={styles.container}>
              <Text>
                正在加载电影数据……
              </Text>
            </View>
        );
      }
      renderMovie(movie){
        return (
            <View style={styles.container}>
              <Image
                  source={{uri: movie.posters.thumbnail}}
                  style={styles.thumbnail}
                  />
              <View style={styles.rightContainer}>
                <Text style={styles.title}>{movie.title}</Text>
                <Text style={styles.year}>{movie.year}</Text>
              </View>
            </View>
        );
      }
    }
5、一些问题
  1. 学习react-native的成本比较高。
  2. 版本更新太快。
  3. 热部署限制
 
posted @ 2016-09-18 13:37  venkyhu  阅读(283)  评论(0)    收藏  举报