React Native入门-实战解析(上)

来自Leo的原创博客,转载请著名出处

我的stackoverflow


概述

随着app端越来越复杂,迭代越来越快,很多app采用原生+html5的方式来实现,然后不知道什么时候,它就有了个高大上的名字 - hybrid app。类似的框架也很多,比较有名的有

这种app的原理是,用webview来实现类似原生的界面,也就是用h5写的代码是运行在webview里的。优点很明显

  • 动态部署(不需要每次通过应用商店的审核,尤其是iOS,审核有时候真的觉得两颗蛋不够疼的。)
  • 界面灵活(用h5来写的界面要比原生代码灵活的多)
  • 开发迅速(一套代码,iOS,安卓都可以跑;不管是安卓还是iOS,用原生的代码实现类似webview的页面,布局什么的都是很复杂的一件事情)

同样,缺点也很明显

- 性能相对较差(这一点在安卓上尤其明显,安卓的webview性能真的很差,而且安卓机型较多)

- 数据处理能力较差,跑在webview里的程序,而且JavaScript是单线程的,所以很难利用好多核多线程,

- 和硬件组建的交互较差,例如相册,蓝牙,motion等。


React Native

React native是facebook公司推出的一个app开发框架,facebook也有很多其他的框架,在这里都可以找到。

使用纯react native开发的时候,实际的开发语言是JavaScript和框架React。写一套代码,同时运行在多个平台上。

和上文提到的hybrid app最大的区别是

用Reactive Native开发的时候,实际运行的都是原生的代码

目前React Native支持

  • >=Android 4.1
  • >= iOS 7.0

它的优点

  • 可以动态部署,因为是用JS写的,并不需要编译,所以可以在运行期动态的从服务器下载,并且执行。
  • 开发期间,修改界面的时候,只需要Command+R来刷新即可,不需要每次修改都蛋疼的重新编译
  • 支持和原生代码混合编程,所以,对于那些性能要求较高,数据处理复杂的页面,仍然可以用原生的代码来实现。

如果你没有任何的JS和React基础

可以先看看,我之前的这篇JS和React的基础文章


本文最终的效果

本文的目的是实现一个从网络获取数据,加载到ListView,然后点击某一行可以跳转到详情页。


React Native环境搭建

由于本文侧重的是如何使用React Native进行开发,所以并不会详细讲解如何安装和搭建环境。可以参考官方文档,搭建很简单

官方文档链接

有几点提一下

  • 最好是Mac电脑,OS X系统,因为iOS运行环境需要OSX
  • iOS目前需要XCode 7 +
  • 安卓需要Android SDK,和模拟器

文档

关于React Native的文档,在这里你都可以找到,这个系列我不会翻译facebook的文档。能阅读英文文档是程序员的一项基本技能,但是我会在使用的时候简单提一下


创建一个工程

打开终端,cd到想要的目录去,然后

react-native init LeoRNWeather

可以看到生成了一个LeoRNWeather的文件夹,这个文件夹的默认的文件如下

android  //安卓的工程
index.ios.js //iOS的程序入口文件
node_modules //
index.android.js //安卓的入口文件
ios         //iOS的工程
package.json //全局的描述信息,本文就使用默认的了

对了我使用的IDE,是Atom

然后,可以手动打开 ios 目录下的XCode 工程,然后点击运行,如果能见到下面截图,代表运行成功


入门

记住,React Native没有CSS,所有的实现都是JS的语法。当你打开index.ios.js的时候,大概能发现几个模块

导入的模块,要先导入才能使用

import React, {
    ****
} from ‘react-native‘;

样式布局定义,用JS的语法,由StyleSheet创建,其中样式使用了React的FlexBox,让布局变的十分简单

const styles = StyleSheet.create({
   //*
  welcome: {
    fontSize: 20,
    textAlign: ‘center‘,
    margin: 10,
  },
  //*
});

视图组件,视图继承自Component,可以在文档上找到很多Components

class LeoRNWeather extends Component {
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
      </View>
    );
  }
}

可以看看这一行,可以看到React的视图语法和H5类似,标准的XML格式。

<Text style={styles.welcome}>
      Welcome to React Native!
</Text>

!!!!我们删除这个文件里的全部内容,然后替换成React的风格代码

这时候代码如下

import React, {
  AppRegistry,
  Component,
  StyleSheet,
  View,
  ListView,
  Text,
} from ‘react-native‘;

var LeoRNWeather = React.createClass({
    render(){
      return (
        <View style= {styles.container}>
          <Text style={styles.blackText}>这是一个标题</Text>
        </View>
      );
    }
});
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: ‘white‘,
    justifyContent: ‘center‘,
  },
  blackText:{
    fontSize:20,
    color:‘rgb(0,0,0)‘,
    backgroundColor:‘rgba(255,255,255,0)‘,
    textAlign:‘center‘,
    marginLeft:10,
  },
});
AppRegistry.registerComponent(‘LeoRNWeather‘, () => LeoRNWeather);

效果


添加导航栏

这里提一下,在React Native中,导航栏有两种

  • Navigator,大部分的情况下使用这个,由facebook的react native团队进行开发,一直在维护,同时支持iOS和安卓,由于在导航切换的时候需要进行大量的加载,所以会占用JS线程较多时间。
  • NavigatorIOS,很少使用,由开源社区开发,有很多bug,仅仅支持iOS。但是内部由原生的UINavigationController实现,所以实际运行的时候,和原生的iOS导航一样,有一样的动画

本文使用NavigatorIOS,react native的相关资料还不是很多,一定要会看英文文档,NavigationIOS的文档可以在这里找到

在顶部import引入

  NavigatorIOS,

然后,重写LeoRNWeather,增加导航栏,其中

  • initialRoute 定义最初的页面,类似iOS中的rootViewController,title表示标题,component表示渲染的对象,是Component的子类
var LeoRNWeather = React.createClass({
  render: function() {
    return (
      <NavigatorIOS
        style={styles.container}
        initialRoute={{
          title: ‘主页‘,
          component: ListScreen,
        }}
      />
    );
  }
});

创建ListScreen

var ListScreen = React.createClass({
    render(){
      return (
        <View style= {styles.container}>
          <Text style={styles.blackText}>blog.csdn.net/hello_hwc</Text>
        </View>
      );
    }
});

然后, Save,选择模拟器,command+R刷新,可以看到效果(修改了文字)


添加背景图

首先,在目录里添加一张图片

Tips:当向iOS工程中Images.xcassets添加了图片或者android添加了res/drawable添加图片的时候,需要重新编译

然后,将index.ios.js修改成如下

import React, {
  AppRegistry,
  Component,
  StyleSheet,
  View,
  ListView,
  Text,
  NavigatorIOS,
  Image,
} from ‘react-native‘;
var ListScreen = React.createClass({
    render(){
      return (
        <Image source={require(‘./img/background.png‘)} style={styles.backgroundImg}>
          <Text style={styles.whiteText}>blog.csdn.net/hello_hwc</Text>
        </Image>
      );
    }
});

var LeoRNWeather = React.createClass({
  render: function() {
    return (
      <NavigatorIOS
        style={styles.container}
        initialRoute={{
          title: ‘主页‘,
          component: ListScreen,
        }}
      />
    );
  }
});

const styles = StyleSheet.create({
  backgroundImg:{
    flex:1,
    width: null,
    height: null,
    flexDirection: ‘row‘,
    justifyContent: ‘center‘,
    alignItems: ‘center‘,
  },
  whiteText:{
    fontSize:20,
    color:‘rgb(255,255,255)‘,
    backgroundColor:‘rgba(255,255,255,0)‘,
    textAlign:‘left‘,
    marginLeft:10,
  },
  container: {
    flex: 1,
    backgroundColor: ‘white‘,
    justifyContent: ‘center‘,
  },
  blackText:{
    fontSize:20,
    color:‘rgb(0,0,0)‘,
    backgroundColor:‘rgba(255,255,255,0)‘,
    textAlign:‘center‘,
    marginLeft:10,
  },
});

AppRegistry.registerComponent(‘LeoRNWeather‘, () => LeoRNWeather);

效果图

Tips

通过设置flex为1来让宽度高度填充100%,通过height,width为null,来让Image填充屏幕

通过设置父视图的alignItems:‘center‘ flexDirection:‘column‘来设置水平居,alignItems:‘center‘ flexDirection:‘row‘来设置垂直居中

关于Flexbox布局,可以参考这片文章,写的非常详细


进行网络请求

React Native网络请求的文档可以在这里找到,在React中,网络请求使用Fetch

例如,你可以这样去调用一个POST请求

fetch(‘https://mywebsite.com/endpoint/‘, {
  method: ‘POST‘,
  headers: {
    ‘Accept‘: ‘application/json‘,
    ‘Content-Type‘: ‘application/json‘,
  },
  body: JSON.stringify({
    firstParam: ‘yourValue‘,
    secondParam: ‘yourOtherValue‘,
  })
})

由于网络请求是一个异步的请求,所以,它返回的是一个Promise对象,对于这个对象,有两种处理方式

  • 同步处理then和catch
  • 异步处理,async/await

还有一个API是XMLHttpRequest,它是建立在iOS网络请求api之上的,本文不做讨论。

由于本文是这个React Native系列的第一篇,所以处理方式采用同步处理。简单直接。

在类ListScreen中,添加如下两个方法

  //Component挂载完毕后调用
  componentDidMount() {
    this.fetchData();
  },
  fetchData() {
   fetch(REQUEST_URL)
     .then((response) => response.json())
     .then((responseData) => {

     })
     .done();
  },

这里的REQUEST_URL是一个全局变量

var REQUEST_URL = ‘https://raw.githubusercontent.com/LeoMobileDeveloper/React-Native-Files/master/person.json‘;

然后,save,command+R刷新模拟器,会发现Log如下

2016-04-21 13:53:49.563 [info][tid:com.facebook.React.JavaScript] [ { nickname: ‘Leo‘, realname: ‘WenchenHuang‘ },
  { nickname: ‘Jack‘, realname: ‘SomethingElse‘ } ]

为了显示到ListView中,我们要把网络请求来的数据存储下来,为ListScreen添加如下方法

  • 用loaded来判断网络数据是否加载完毕
  • 用users来存储实际的的网络数据,这里因为users是ListView的dataSource,所以用ListView的DataSource来初始化
  //自动调用一次,用来设置this.state的初始状态
  getInitialState: function() {
    return {
      loaded: false,
      users: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }),
    };
  },

然后修改fetchData方法,在加载完毕后保存数据

  fetchData() {
   fetch(REQUEST_URL)
     .then((response) => response.json())
     .then((responseData) => {
       this.setState({
         users: this.state.users.cloneWithRows(responseData),
         loaded: true,
       });
     })
     .done();
  },

Tips:this.setState会触发render重新调用,进行重绘


写出一个列表

移动开发中,列表是一个非常常用的控件。(iOS中的Tableview,android中的listview)。

ListView的文档链接

ListView的优点是,当视图离开屏幕的时候,会被复用或者移除,降低内存使用。关于ListVIew,ReactNative团队进行了很多优化,比如event-loop只渲染一个cell,将渲染工作分成很多个小的碎片执行,来防止掉帧。

如何使用ListView

最少需要以下两个

  • dataSource,一个简单数组来描述MVC中的model,类似于iOS中的dataSource
  • renderRow,返回一个视图组建.类似于iOS中的cellForRowAtIndexPath
  • renderSeparator,一般也需要这个方法,来说生成一个分隔线

当然,listView也支持很多,比如像iOS那样的section header,header,footer,以及很多的事件回调,在listView的文档里,你都可以找到。

这时候的ListScreen类如下

var ListScreen = React.createClass({
  getInitialState: function() {
    return {
      loaded: false,
      users: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }),
    };
  },
  componentDidMount() {
    this.fetchData();
  },
  fetchData() {
   fetch(REQUEST_URL)
     .then((response) => response.json())
     .then((responseData) => {
       this.setState({
         users: this.state.users.cloneWithRows(responseData),
         loaded: true,
       });
     })
     .done();
  },

  render(){
   if (!this.state.loaded) {
     return this.renderLoadingView()
    }
   return this.renderList()
  },

  renderLoadingView() {
    return (
      <Image source={require(‘./img/background.png‘)} style={styles.backgroundLoading}>
      <ActivityIndicatorIOS
        style={[styles.centering, {height: 80}]}
        size="large"
        color="#ffffff"
       />
      </Image>
    );
  },

  renderList(){
    return (
      <Image source={require(‘./img/background.png‘)} style={styles.backgroundImg}>
        <ListView
          dataSource={this.state.users}
          renderRow={this.renderRow}
          style={styles.fullList}
          renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator} />}
         />
      </Image>
    );
  },
  renderRow(user){
    return (
      <TouchableHighlight
        onPress={() => this.rowClicked(user)}
        underlayColor = ‘#ddd‘>
      <View style={styles.rightCongtainer}>
        <Text style={styles.whiteText}>{user.nickname}</Text>
        <Text style={styles.whiteText}>{user.realname}</Text>
      </View>
      </TouchableHighlight>
    );
  },
  rowClicked(user){
    console.log(user);
  },
});

Styles如下

const styles = StyleSheet.create({
  backgroundImg:{
    flex:1,
    width: null,
    height: null,
    flexDirection: ‘row‘
  },
  backgroundLoading:{
    flex:1,
    width: null,
    height: null,
    alignItems: ‘center‘,
    justifyContent: ‘center‘,
    flexDirection: ‘row‘
  },
  thumbnail: {
    width: 60,
    height: 60,
  },
  rightCongtainer:{
    flex:1,
  },
  fullList:{
    flex:1,
    paddingTop: 64,
  },
  separator: {
   height: 0.5,
   backgroundColor: ‘rgba(255,255,255,0.5)‘,
 },
 centering: {
    alignItems: ‘center‘,
    justifyContent: ‘center‘,
  },
  whiteText:{
    fontSize:20,
    color:‘rgb(255,255,255)‘,
    backgroundColor:‘rgba(255,255,255,0)‘,
    textAlign:‘left‘,
    marginLeft:10,
  },
  blackText:{
    fontSize:20,
    color:‘rgb(0,0,0)‘,
    backgroundColor:‘rgba(255,255,255,0)‘,
    textAlign:‘center‘,
    marginLeft:10,
  },
  container: {
    flex: 1,
    backgroundColor: ‘white‘,
    justifyContent: ‘center‘,
  },
});

这时候,save,command+R后,发现再网络请求的时候会先显示小菊花转转转,然后加载完毕之后,显示一个List


加载Spinner(仅适用于iOS)

这个在上面的代码中提到了

renderLoadingView() {
    return (
      <Image source={require(‘./img/background.png‘)} style={styles.backgroundLoading}>
      <ActivityIndicatorIOS
        style={[styles.centering, {height: 80}]} //风格
        size="large" //大小
        color="#ffffff" //颜色
       />
      </Image>
    );
  },

控制台打印

上文的代码里提到

   rowClicked(user){
    console.log(user);
   },

使用console.log来实现控制台

这时候,我们在点击某一行,会看到XCode中输出

在Chrome中调试

使用Command+control+Z来调出调试窗口,然后选择Debug in chrome

这时候,App会和Chrome建立一个socket连接,这样在Chrome中就可以进行调试了。

打开Chrome开发者工具

点击某一行,就会发现在chrome的控制台进行log了


添加一个详情页,并且传值

新建一个Component来表示详情页

var DetailScreen = React.createClass({
  render(){
    return (
      <View style= {styles.container}>
        <Text style={styles.blackText}>{this.props.user.nickname}</Text>
        <Text style={styles.blackText}>{this.props.user.realname}</Text>
      </View>
    );
  }
});

然后,在rowClick中,跳转到详情页

  rowClicked(user){
    console.log(user);
    this.props.navigator.push({
      title: "详情页",
      component: DetailScreen,
      passProps: {user:user},
    });
  },

Tips:

  • NavigatorIOS可以通过this.props.navigator来访问
  • 通过 this.props.navigator.push来跳转,通过passProps: {user:user}来传递值
  • 每个Component的类都有两个全独享,this.props表示参数,this.state表示当前的状态。可以用来存储和传递数据

简单提一下React Native的性能

在RN中,主要有两个线程

  • JavaScript线程
  • 主线程(UI线程)

其中,JavaScript是React Native的JS代码执行线程,React Native的触摸处理,网络请求,视图配置,以及app的业务逻辑都是发生在这里的。主线程是实际原生代码绘制视图的执行线程。使用React Native的时候,往往会遇到JavaScript线程执行逻辑过多,没有办法及时响应UI线程,导致掉帧.所以,React Native的性能,较纯原生的还是要差一些的


后续

Reactive Native实战解析(中)会继续讲解一些基础控件的适用,然后也会写一个demo的app,Reactive Native实战解析(下)会写一个相对完善点的应用,作为这个入门系列的终结。然后,计划写一两篇混合编程的,最近比较忙,这个系列慢慢更新吧



附录,最终的index.ios.js全部代码

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

import React, {
  AppRegistry,
  Component,
  StyleSheet,
  ListView,
  Text,
  View,
  Image,
  ActivityIndicatorIOS,
  Navigator,
  TouchableHighlight,
  TouchableOpacity,
  NavigatorIOS,
} from ‘react-native‘;

var REQUEST_URL = ‘https://raw.githubusercontent.com/LeoMobileDeveloper/React-Native-Files/master/person.json‘;

var ListScreen = React.createClass({
  getInitialState: function() {
    return {
      loaded: false,
      users: new ListView.DataSource({
        rowHasChanged: (row1, row2) => row1 !== row2,
      }),
    };
  },
  componentDidMount() {
    this.fetchData();
  },
  fetchData() {
   fetch(REQUEST_URL)
     .then((response) => response.json())
     .then((responseData) => {
       this.setState({
         users: this.state.users.cloneWithRows(responseData),
         loaded: true,
       });
     })
     .done();
  },

  render(){
   if (!this.state.loaded) {
     return this.renderLoadingView()
    }
   return this.renderList()
  },

  renderLoadingView() {
    return (
      <Image source={require(‘./img/background.png‘)} style={styles.backgroundLoading}>
      <ActivityIndicatorIOS
        style={[styles.centering, {height: 80}]}
        size="large"
        color="#ffffff"
       />
      </Image>
    );
  },

  renderList(){
    return (
      <Image source={require(‘./img/background.png‘)} style={styles.backgroundImg}>
        <ListView
          dataSource={this.state.users}
          renderRow={this.renderRow}
          style={styles.fullList}
          renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator} />}
         />
      </Image>
    );
  },
  renderRow(user){
    return (
      <TouchableHighlight
        onPress={() => this.rowClicked(user)}
        underlayColor = ‘#ddd‘>
      <View style={styles.rightCongtainer}>
        <Text style={styles.whiteText}>{user.nickname}</Text>
        <Text style={styles.whiteText}>{user.realname}</Text>
      </View>
      </TouchableHighlight>
    );
  },
  rowClicked(user){
    console.log(user);
    this.props.navigator.push({
      title: "详情页",
      component: DetailScreen,
      passProps: {user:user},
    });
  },
});

var DetailScreen = React.createClass({
  render(){
    return (
      <View style= {styles.container}>
        <Text style={styles.blackText}>{this.props.user.nickname}</Text>
        <Text style={styles.blackText}>{this.props.user.realname}</Text>
      </View>
    );
  }
});

var LeoRNWeather = React.createClass({
  render: function() {
    return (
      <NavigatorIOS
        style={styles.container}
        initialRoute={{
          title: ‘主页‘,
          component: ListScreen,
        }}
      />
    );
  }
});

const styles = StyleSheet.create({
  backgroundImg:{
    flex:1,
    width: null,
    height: null,
    flexDirection: ‘row‘
  },
  backgroundLoading:{
    flex:1,
    width: null,
    height: null,
    alignItems: ‘center‘,
    justifyContent: ‘center‘,
    flexDirection: ‘row‘
  },
  thumbnail: {
    width: 60,
    height: 60,
  },
  rightCongtainer:{
    flex:1,
  },
  fullList:{
    flex:1,
    paddingTop: 64,
  },
  separator: {
   height: 0.5,
   backgroundColor: ‘rgba(255,255,255,0.5)‘,
 },
 centering: {
    alignItems: ‘center‘,
    justifyContent: ‘center‘,
  },
  whiteText:{
    fontSize:20,
    color:‘rgb(255,255,255)‘,
    backgroundColor:‘rgba(255,255,255,0)‘,
    textAlign:‘left‘,
    marginLeft:10,
  },
  blackText:{
    fontSize:20,
    color:‘rgb(0,0,0)‘,
    backgroundColor:‘rgba(255,255,255,0)‘,
    textAlign:‘center‘,
    marginLeft:10,
  },
  container: {
    flex: 1,
    backgroundColor: ‘white‘,
    justifyContent: ‘center‘,
  },
});

AppRegistry.registerComponent(‘LeoRNWeather‘, () => LeoRNWeather);
时间: 2024-10-08 01:49:59

React Native入门-实战解析(上)的相关文章

React Native 入门宝典

声明:该书的笔者为徐嬴老师,一名具有5年IOS开发经验,和两年RN开发经验的老司机. 原文可以在gitbook上找到 笔者只是为他的书中提的的一些列问题,进行有偿答疑. 有偿答疑.本书将持续保持更新,有关问题可以加群讨论. 正在上传...取消 简介 笔者在研究ReactNative过程中,发现其中文资料相对较少,已出版的大部分图书资料都已过时.Facebook中的ReactNative开发团队以每月更新一版的速度在向前推进版本. 为更好的让广大开发者快速入门ReactNative,笔者结合自身开

【腾讯Bugly干货分享】React Native项目实战总结

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 "8小时内拼工作,8小时外拼成长"这是大家共同的理想.除了每天忙于工作外,我们都希望能更多地区吸收领域内的新知识与新技能,从而走向人生巅峰. Dev Club 是一个交流移动开发技术,结交朋友,扩展人脉的社群,成员都是经过审核的移动开发工程师.每周都会举行嘉宾分享,话题讨论等活动. 上一期我们邀请了腾讯SNG工程师&qu

React Native入门(二)Atom+Nuclide安装、配置与调试

相关文章 React Native入门 前言 上一篇文章我们搭建了开发环境,并写了个Hello World.这一节我们来学习React Native的开发IDE:Atom+Nuclide的安装.配置与调试.本文所讲的内容只适用于Mac平台. 1.开发IDE选择 React Native的开发IDE有很多种,比如FaceBook 官方推荐的 Atom+Nuclide.Android Studio的同门WebStorm(收费).Sublime Text 3.Visual Studio Code和De

React Native入门(三)组件的Props(属性)和State(状态)

相关文章 React Native入门系列 前言 在Android或者iOS开发中我们会用到很多控件,这些控件会有很多的属性.样式等等.同样的,React Native中的组件也有属性.样式和状态. 1.Props(属性) 组件创建时会设置一些参数来定制这个组件,这些参数就是属性,属性一旦设定,在组件的生命周期中就不会改变.下面拿Image的source属性和Text的onPress属性作为举例. Image的source属性 import React, {Component} from 're

React Native 入门基础知识总结

中秋在家闲得无事,想着做点啥,后来想想,为啥不学学 react native.在学习 React Native 时, 需要对前端(HTML,CSS,JavaScript)知识有所了解.对于JS,可以看看阮一峰老师的<ECMAScript 6 入门>这篇文章.里面涉及很多 ES6 的新特性.我之前也是看了阮老师的文章做了一些学习笔记 ES6 学习笔记. 1.环境搭建 环境搭建中文教程,点击跳转RN中文社区 :http://reactnative.cn/docs/0.40/getting-star

React Native入门-刘望舒

React Native入门(一)环境搭建与Hello World React Native入门(二)Atom+Nuclide安装.配置与调试 React Native入门(三)组件的Props(属性)和State(状态)

《React Native入门与实战》读书笔记(1)

ReactNative介绍 它的底层引擎是JavaScript Core,调用的是原生组件而非HTML5组件(HTML+CSS+JavaScript构建的组件).运行时,可以做到与Native App媲美的体验,同时因为JavaScript代码可以使用后端强大的Web方式管理,既可以做到高效开发,也可以做到快速部署和问题热修复.React Native APP运行在客户的手机上,而控制端可以在后端,可以充分发挥Web的能力,就像一个牵线木偶,任凭你表演. 环境搭建 安装Node.js最新版本 h

React Native运行原理解析

http://blog.csdn.net/xiangzhihong8/article/details/52623852 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] Facebook 于2015年9月15日推出react native for Android 版本, 加上2014年底已经开源的iOS版本,至此RN (react-native)真正成为跨平台的客户端框架.本篇主要是从分析代码入手,探讨一下RN在安卓平台上是如何构建一套JS的运行框架. 一. 整体架构 RN

React Native入门(一)环境搭建与Hello World

前言 目前关于React Native的教程很多,官方文档写的也不错,但是感觉大部分教程写的不是很清楚,导致我各种碰壁.因此我来写一个简洁的教程.本篇文章基于React Native 0.43,只适用于用Windows平台的Android开发者. 1.配置React Native 首先我们要先来安装一些软件,如下所示. Chocolatey Chocolatey是一个Windows上的命令行包管理器,安装了Chocolatey就可以通过命令行来安装一些我们需要软件.我们打开cmd命令行程序使用如