本文由前人经验加自己实践总结而产生,环境是window平台,主要是android方面。
首先附上RN中文官网
一 、基础环境
1、windows 平台搭建开发环境关键步骤
1) 安装JDK
2) 安装SDK
3) 安装C++环境 2010前不能用,推荐下载vs c++ 2013(25MB)
4) 安装Node js
5) 安装Git
6)安装React-native 在终端输入命令: npm install -g react-native-cli
7)提示:建议在命令之前配置国内镜像,节约时间
npm config set registry https://registry.npm.taobao.org
npm config set disturl https://npm.taobao.org/dist
2、npm基本命令
npm install -g react-native-cli react native 安装,一台机器上只运行一次
react-native init HelloWorld 在当前目录新建一个HelloWorld工程
react-native start 启动packager
react-native run-android 运行当前项目在设备上,需要在根目录(package.json)
npm start 如果packager没有正常运行时,启动packager,根目录
adb reverse tcp:8081 tcp:8081 把设备地址指向主机地址,如果不可行,摇晃手机,Dev Settings Debug server host&port for device 主机地址+端口 :192.168.1.1:8081
npm install 安装package.json中配置的依赖,需在根目录
npm i xxxx - -save 安装第三方库,根目录
3、IDE 推荐
Visual studio code 方便查看目录结构,内置RN插件和NPM管理。
Android studio (只限于打开RN项目中的 android 项目)识别android项目,可当作正常android原生应用进行开发。
WebStorm 识别JSX语法,能做简单提示。
4、填坑过程
1)Android调试需要打开悬浮窗口权限,OS在6.0以上需要手动,部分手机默认关闭了悬浮窗权限也需要手动打开
2) 调试的时候reload 需要packager 处于运行状态
3) 最好使用同一个域的网络,调试时找不到npm服务,请控制台中 adb reverse tcp:8081 tcp:8081 把设备地址指向主机地址,如果不可行,摇晃手机,Dev Settings Debug server host&port for device 主机地址+端口 :192.168.1.1:8081
4)如果无法安装,是不是工程中的第三方包没安装 先执行npm install 安装package.json中配置的依赖,需在根目录。
5)我学RN时官网RN版本是0.24,当时官网上写法是ES5,在论坛中遇到的都是ES6写法,工程务必统一ES6 并先掌握ES6。
二、RN开发必备技能
1、入口组件注册
var React = require('react-native');
var {AppRegistry} = React;
var IndexView = require('./IndexView');
var testdemo = React.createClass({
render: function() {
return (
<IndexView/>
);
}
});
AppRegistry.registerComponent('testdemo', () => testdemo);
上面的写法是ES 5 ,一个工程入口注册,可使用import 和export default class 替换为ES6。
2、导航器定义
var IndexView =React.createClass({
getInitialState(){…},
compoentWillMount(){…},
compoentDidMount(){…},
compoentUnmount(){…},
render(){
return(
<Navigator
initialRoute={‘defaultName’,compent}
configureScene={(route)=>{return Navigator.SceneConfigs.FloatfromRight}}
renderScene = { (route,navigator)=>{
let Component = route.component;
retrun <Component {…route.params} navigator = {navigator}/>
} }
/> );},
});
Module.exports = indexView;
同样是ES5写法不再诉说,这里包含了完整的生命周期和Navigator,Navigator 必须定义三个属性:
1、initialRoute 即指定一个默认启动的页面;
2 、configureScene 场景切换配置,可以配置入场动画;
3、renderScene 渲染场景,需要指定一个route和navigator;
retrun <Component {…route.params} navigator = {navigator}/>
这里的… 意思是把navigator及所有参数拷贝,在子组件中才可服用this.props.xxx
3、定义一个组件
this.props 的参数来自父组件,详细定义见上面。这里使用最新的写法。
Import React,{Component} from ‘react’;
Import {View,Image,Text,ListView,StyleSheet};
Export default class GirdView extends Component{
Constructor(props){super(props) …}
compoentWillMount(){…}
compoentDidMount(){…}
compoentUnmount(){…}
render(){ return( <View style={style.container})>…</View> }
}
Const styles = StyleSheet.create({
Container:{flex:1},
Item:{width:50,height:50},
Font:{color:’red’,fontSize:20},…
});
4、引用一个组件
应用时可以传递参数到自组件,把需要传递的参数定义在属性集中,子组件通过this.props.属性名 获取值。
Import GirdView form ‘./ ../xxxx’;
Render({return( <Gird/> );});
5、Js 调用 Java
在java中定义方法:
1
Public class AModule extends ReactContextBaseJavaModule{
Public AModule(ReactApplicationContext context){…}
Public String getname(){ return ‘AModule’}
}
2
Public class AModulePackage implements ReactPackage{
Public List<ViewManager> createNativeModules(context){
List<NativeModule> modules=new ArrayList<>();
Return Modules.add(new AModule(context));
}
}
3、在MainActivity中初始化AModule
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new AModulePackage ()); //类名替换成你的Package类的名字.
4、把AModule封装成一个JavaScript模块 :AModule.js
var { NativeModules } = require('react-native');
module.exports = NativeModules.ToastAndroid;
5、在JS中调用java api
Var NativeApi =require(‘xxx’);//xxx Amodule.js 相对路径
6、Java 向 JS 发送事件
1、发送事件
public static void sendEvent(ReactContext reactContext,
String eventName,
Object params) {
if (!reactContext.hasActiveCatalystInstance() || !reactContext.hasCurrentActivity()) {
Log.i("tag", "eventName=" + eventName);
return;
}
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
2、注册事件
在js中定义事件接收器
import RCTDeviceEventEmitter form 'RCTDeviceEventEmitter';
Var callListener = RCTDeviceEventEmitter.addListener(listenerName,function{});