release 热更新:pushy,codepush
react-native init MyApp --version 0.44.3
如果直接执行react-native init MyApp 的话会默认使用RN的最新版本,以上命令则可选择之前稳定的版本,通常在初始化时需要作出以上处理
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';//注册Text组件,Text组件是专门用来显示文本的组件,以此类推Image组件是用来显示图片的,因此,项目中需要用到什么UI控件,都可以在这里进行注册
class HelloWorldApp extends Component {
render() {//在render方法中返回一些用于渲染结构的JSX语句
return (
<Text>Hello world!</Text>
);//JSX语法,在js中嵌入xml
}
}
// 注意,这里用引号括起来的'HelloWorldApp'必须和你init创建的项目名一致
AppRegistry.registerComponent('HelloWorldApp', () => HelloWorldApp);
大多数组件在创建时就可以使用各种参数来进行定制。用于定制的这些参数就称为props(属性)。
以常见的基础组件Image为例,在创建一个图片时,可以传入一个名为source的prop来指定要显示的图片的地址,以及使用名为style的prop来控制其尺寸。
import React, { Component } from 'react';
import { AppRegistry, Image } from 'react-native';
class Bananas extends Component {
render() {
let pic = {
uri: 'https://upload.wikimedia.org/wikipedia/commons/d/de/Bananavarieties.jpg'
};
return (
<Image source={pic} style={{width: 193, height: 110}} />// source和style为image控件的属性,分别控制内容和位置
);
}
}
AppRegistry.registerComponent('Bananas', () => Bananas);
自定义的组件也可以使用props。通过在不同的场景使用不同的属性定制,可以尽量提高自定义组件的复用范畴。只需在render函数中引用this.props,然后按需处理即可
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View
} from 'react-native';
class Head extends Component {//自定义类类名首字母大写,否则会找不到这个类
render() {
return (
<Text>Hello---{this.props.content}!</Text>
);
}
}
export default class HelloWorld extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Head content='Rexxar' />
<Head content='Jaina' />
<Head content='Valeera' />
</View>
);
}
}
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
我们使用两种数据来控制一个组件:props和state。props是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用state。
一般来说,你需要在constructor中初始化state(译注:这是ES6的写法,早期的很多ES5的例子使用的是getInitialState方法来初始化state,这一做法会逐渐被淘汰),然后在需要修改时调用setState方法。
假如我们需要制作一段不停闪烁的文字。文字内容本身在组件创建时就已经指定好了,所以文字内容应该是一个prop。而文字的显示或隐藏的状态(快速的显隐切换就产生了闪烁的效果)则是随着时间变化的,因此这一状态应该写到state中。
class Blink extends Component {
constructor(props){//在constructor(构造器)初始化属性的state
super(props);
this.state = { showtext : true};
setInterval(() => {
this.setState(previousState => {
return { showtext : !previousState.showtext };
});
}, 1000);
}
render() {
let display = this.state.showtext ? this.props.text : ' ';
return (
<Text>{display}</Text>
);
}
}
export default class HelloWorld extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Blink text = 'i love to blink'/>
<Blink text = '闪闪闪'/>
</View>
);
}
}
样式名遵循驼峰命名法则 实际开发建议使用 StyleSheet.create集中定义样式
style可以传入数组,数组中居后的优先级较高。
export default class HelloWorld extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<Text style = {styles.bigblue}> bigblue </Text>
<Text style = {styles.red}> red </Text>
<Text style = {[styles.red, styles.bigblue]}>red, blue</Text>//这里就展示了数组中的居后对象优先级更高,因此,本段文字显示为大蓝
<Text style = {[styles.bigblue, styles.red]}>bigblue, red</Text>//这里就展示了数组中的居后对象优先级更高,因此,本段文字显示为红
</View>
);
}
}
const styles = StyleSheet.create({//定义一个样式表,单词别写错了,否则报奇怪的错误
bigblue : {
color : 'blue',
fontWeight : 'bold',
fontSize : 30
},
red : {
color : 'red',
},
});
最简单的给组件设定尺寸的方式就是在样式中指定固定的width和height。React Native中的尺寸都是无单位的,表示的是与设备像素密度无关的逻辑像素点。
export default class HelloWorld extends Component {
render() {
return (
<View style={{alignItems: 'center'}}>
<View style = {{width : 50, height : 50, backgroundColor : 'powderblue'}} />
<View style = {{width : 100, height : 100, backgroundColor : 'skyblue'}} />
</View>
);
}
}
====================
注意: Text的style的写法
<Text stlye = { }></Text>
View的style
<View style = {{ }} />
====================
在组件样式中使用flex可以使其在可利用的空间中动态地扩张或收缩。一般而言我们会使用flex:1来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了flex:1,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间flex值的比)。
组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的。
export default class HelloWorld extends Component {
render() {
return (
<View style={{flex : 1}}>
<View style = {{flex : 1, backgroundColor : 'powderblue'}} />
<View style = {{flex : 2, backgroundColor : 'skyblue'}} />
</View>
);
}
}
包含三个属性
flexDirection:在组件的style中指定flexDirection可以决定布局的主轴。子元素是应该沿着水平轴(row)方向排列,还是沿着竖直轴(column)方向排列呢?默认值是竖直轴(column)方向。
- row 从左往右
- column 从上向下
- row-reverse 从右向左
- column-reverse 从下往上
Justify Content: 在组件的style中指定justifyContent可以决定其子元素沿着主轴的排列方式。子元素是应该靠近主轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start、center、flex-end、space-around以及space-between。
- flex-start
- center
- flex-end
- space-between
- space-around
Align Items:在组件的style中指定alignItems可以决定其子元素沿着次轴(与主轴垂直的轴,比如若主轴方向为row,则次轴方向为column)的排列方式。子元素是应该靠近次轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start、center、flex-end以及stretch。
注意:要使stretch选项生效的话,子元素在次轴方向上不能有固定的尺寸。以下面的代码为例:只有将子元素样式中的width: 50去掉之后,alignItems: 'stretch'才能生效。
具体的布局变化可以通过代码来观察
export default class HelloWorld extends Component {
render() {
return (
<View style={{flex : 1, flexDirection : 'row', justifyContent : 'space-around', alignItems : 'stretch'}} >
<View style = {{width : 50, backgroundColor : 'powderblue'}} />
<View style = {{width : 50, backgroundColor : 'skyblue'}} />
<View style = {{width : 50, backgroundColor : 'steelblue'}} />
</View>
);
}
}
TextInput是一个允许用户输入文本的基础组件。它有一个名为onChangeText的属性,此属性接受一个函数,而此函数会在文本变化时被调用。另外还有一个名为onSubmitEditing的属性,会在文本被提交后(用户按下软键盘上的提交键)调用。
import React, { Component } from 'react';
import { AppRegistry, Text, TextInput, View } from 'react-native';
class PizzaTranslator extends Component {
constructor(props) {
super(props);
this.state = {text: ''};
}
render() {
return (
<View style={{padding: 10}}>
<TextInput
style={{height: 40}}
placeholder="Type here to translate!"
onChangeText={(text) => this.setState({text})}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.text.split(' ').map((word) => word && '🍕').join(' ')}
</Text>
</View>
);
}
}
FlatList:调用tableview的plain格式 通过data属性设置数据源 通过renderItem:设置cell的内容和样式
export default class HelloWorld extends Component {
render(){
return(
<View style = {styles.container}>
<FlatList
data = {[//提供数据源
{key: 'Devin'},
{key: 'Jackson'},
{key: 'James'},
{key: 'Joel'},
{key: 'John'},
{key: 'Jillian'},
{key: 'Jimmy'},
{key: 'Julie'},
]}
renderItem = {({item}) => <Text style={styles.item}>{item.key}</Text>}//根据
/>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex : 1,
paddingTop : 22,
},
item : {
padding: 10,
fontSize: 18,
height: 44,
color : 'red',
},
})
SectionList:调用tableview 的group样式
import React, { Component } from 'react';
import {
AppRegistry,
Text,
Button,
StyleSheet,
View,
TouchableOpacity,
Alert
} from 'react-native';
export default class HelloWorld extends Component {
GET(){
fetch('https://www.baidu.com')
.then((response) => response.json()) //把response转为json
.then((responseData) => { // 上面的转好的json
alert(responseData);
})
.catch((error)=> {
alert(error);
})
}
render(){
return(
<View style = {styles.container}>
<Button
onPress = {this.GET}
title="Learn More"
color="#841584"
/>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex : 1,
paddingTop : 22,
},
})
AppRegistry.registerComponent('HelloWorld', () => HelloWorld);
1.首先当然要了解你要集成的React Native组件。
2.创建一个Podfile,在其中以subspec的形式填写所有你要集成的React Native的组件。
3.创建js文件,编写React Native组件的js代码。
4.添加一个事件处理函数,用于创建一个RCTRootView。这个RCTRootView正是用来承载你的React Native组件的,而且它必须对应你在index.ios.js中使用AppRegistry注册的模块名字。
5.启动React Native的Packager服务,运行应用。 根据需要添加更多React Native的组件。 调试。
6.准备部署发布 (比如可以利用react-native-xcode.sh脚本)。
运行Packager
要运行应用,首先需要启动开发服务器(即Packager,它负责实时监测js文件的变动并实时打包,输出给客户端运行)。具体只需简单进入到项目根目录中,然后运行:
$ npm start
Packager只是在开发时需要,便于你快速开发迭代。在正式发布应用时,所有的js文件都会被打包为一整个jsbundle文件离线运行,此时客户端不再需要Packager服务。