接触React Native有一段时间了,鉴于国内资料的缺乏,入门的时候相当痛苦,踩了不少坑,以下的笔记希望可以帮助和我一样有投入RN热情的同伴少走一些弯路,如有纰漏,欢迎大家交流指正
(除了百度、Google这两位无名老师之外,感谢RN中文网和东方耀老师的视频)
当前的编程环境:MacOS 10.11.4,Xcode 7.3.1,Android Studio 2.0,Sublime Text 2(插件配置以下有),RN的版本 0.26
个人推荐用Mac环境,环境配置简单(具体请看RN中文网的配置,有些命令可能会出现权限问题,在命令前面加上sudo),可以做android和ios开发(需要提前安装Xcode)
学习路线(配置完环境):html、css、js入门知识 ---> React JS的入门及生命周期学习(掌握JSX语法) ---> RN组件学习(从View开始) ---> RN的弹性盒布局和API方法学习
环境部分
1.sublime安装插件
(1)使用View > Show Console的方式打开命令行,然后用网络找到的代码安装Package Control(具体方法百度),安装之后重启生效
(2)使用Sublime Text 2 > Preference > Package Control,选择install Package,安装以下插件:
Emmet(有自己的语法,快速写CSS和HTML,文件名要html和css才可以生效)
HTML-CSS-JS Prettify 格式化代码
Spacegray 主题,使整体更好看https://github.com/kkga/spacegray,安装之后Sublime Text 2 > Preference > Settings-User,在里面引用相关的主题(可能要在之前的代码后面加逗号),引用之后立刻生效,具体git上也有详细说明
2.真机调试
相同的部分:USB连接手机,使电脑和手机在同个局域网(连同个wifi或者开电脑热点)
ios:
(1)在命令行中找到项目文件夹,即ls命令可以看到index.ios.js的目录,输入react-native run-ios,启动js服务器,看到 React packager ready. 并且没有报错实施下一步
(2)在项目文件夹中打开 ios -> [项目名称].xcodeproj,找到AppDelegate.m中的jsCodeLocation变量,将里面localhost改为相对应的电脑 ip,然后运行真机,摇晃一下点击Reload JS
android:
(1)配置好ANDROID_HOME环境(具体请百度),输入adb devices可以看到连接的设备
(2)在命令行中找到项目文件夹,即ls命令可以看到index.android.js的目录,输入react-native run-android,启动js服务器,看到 React packager ready. 并且没有服务器启动报错实施下一步
(3)这时如果命令行有** BUILD FAILED **,看这一行上面的报错,有可能是相对应的SDK版本或者ADT的版本不存在(比如默认的ADT 23.0.1版本没下载到电脑),可以打开Android的SDK Manager安装缺失的东西,然后再按照上一个步骤(若没生效,可以重启命令行试试)
(4)这时如果命令行有** BUILD SUCCEEDED **,摇晃手机或者点menu键可以出现一个菜单,点击Dev Settings -> Debug server host & port for device,输入电脑ip,确定,然后后退到主界面,摇晃手机或者点menu键,选择Reload JS
注:可以在手机的浏览器中输入 http://[电脑ip]:8081/index.ios.bundle?platform=ios&dev=true,观察服务器的命令行是否有请求消息输出,来判断手机是否可以访问到电脑的服务器
3.验证JS服务器是否成功开启
在命令行react-native run-ios(或者run-android)之后,有服务器的命令行弹出,这时在电脑浏览器中运行http://[电脑ip]:8081/index.ios.bundle?platform=ios&dev=true,命令行会有请求数据输出,如 [14:16:46] request:/index.ios.bundle?plarform=ios&dev=true [14:16:46] request:/index.ios.bundle?plarform=ios&dev=true (19ms)
编程部分
1.React 生命周期
(1)初始化可以调用的函数:(组件还未渲染)
getDefaultProps 获取实例的默认属性,只调用一次,实例之间共享引用
getInitialState(在RN中constructor(props) 取代)初始化状态,初始化各个实例特有的状态
componentWillMount 组件即将被装载,render之前最后一次修改状态的机会
render 渲染虚拟的DOM节点,只能访问 this.props 和 this.state ,只有一个顶层组件,不允许修改状态和DOM输出
componentDidMount 组件真正被装载,成功render并渲染完成真实DOM之后触发,可以修改DOM
(2)运行中可以调用的函数:
componentWillReceiveProps 组件在接收到属性前触发,父组件修改属性触发,可以修改新属性、修改状态
shouldComponentUpdate 当组件接收到新属性和状态的时候触发,返回false会阻止render调用(小心使用)
componentWillUpdate 将要更新,不能修改属性和状态
render 同上
componentDidUpdate 会在组件更新完调用,可以修改DOM
(3)销毁阶段可以调用的函数:
componentWillUnmount 在组件真正销毁之前调用
2.自定义组件要大写
如var HelloWorld = Recct.createClass();
class Summary extends Component{}
3.RN所支持的最低iOS和Android版本
Android >= 4.1 (API 16)
iOS >= 7.0
4.style优先级
<View style={[styles.base, styles.background]}>.............. </View>
一个View可以接受多个style,如果有多个值,要用中括号 [] 括起来,最右边的元素优先级最高,最右边的style会覆盖之前相同属性的属性值
5.屏幕宽高
(1)设置高度或宽度时不用带单位,默认使用pt
(2)不能用百分比设置宽度高度
(3)可通过Dimensions模块来获取窗口宽高(可通过手动计算获取宽高)
var Dimensions = require(‘Dimensions’);(ES6写法改成import Dimensions from 'Dimensions';)
var {
width,
height
} = Dimensions.get(‘window’)
6.可通过PixelRatio模块来获取像素密度
var pixelRation = PixelRatio.get();
屏幕可以显示的最小像素:1/pixelRation,可以用来设置border的宽度
7.render方法的注意点
(1)render() {return ();} return的最外层有且只有一个View,否则会报错
(2)第一次初始化之后调用。界面呈现后,每次调用this.setState({[属性]:[属性值]})方法,系统都会重新调用render方法渲染视图
8.文本换行: {'\n'}
如<Text>Hello {'\n'} World</Text>,中间会换行
9.外部文件引入写法
ES5写法:
(1)被引用的组件:要在文件底部有module.exports = [组件名称];(删掉入口函数
AppRegistry.registerComponent)。如module.exports = Header;
(2)引用的文件:const [组件名称] = require('./[文件名称不带后缀]’);,如const Header = require('./header');
ES6写法(最新):
(1)被引用的组件:在组件前面加上export default(删掉入口函数AppRegistry.registerComponent)。如export default class LoginUI extends Component
(2)引用的文件:import [组件] from ‘组件的路径’; 。如import LoginUI from './LoginUI.js';
10.引用第三方模块相关命令:(在项目根目录,即package.json文件所在的目录)
npm的命令:
安装模块:npm i [模块名称] —save,如 npm i react-native-swiper —save
查看模块:npm view [模块名称],如 npm view react-native-swiper
删除模块:npm rm [模块名称] —save,如 npm rm react-native-swiper —save
查看帮助命令:nam help [命令],如 nam help i
11.TouchableHighlight、TouchableNativeFeedback、TouchableWithoutFeedback注意点
(1)均可通过onPress方法响应触碰事件,如果还没学会使用箭头函数,就要加上相关函数后面bind(this),否则this.setState会出现找不到对象的情况。 如 onPress={this.clickTarget.bind(this)}
(2)包裹内容的最外层有且只有1个对象,如果里面有多个对象,最外层用一个VIew包裹起来
(3)Text自带onPress方法,如果不需要交互效果,如按钮的点击变色,可以直接用Text实现点击事件,如
<Text onPress={this.clickTarget.bind(this)}>click me</Text>
暂时先到这里,如有纰漏,欢迎大家交流指正