1.Hello world
import React, { Component } from 'react';
import { AppRegistry, Text } from 'react-native';
class myFirstApp extends Component {
render() {
return (
<Text>Hello world!</Text>
);
}
}
AppRegistry.registerComponent('myFirstApp', () => myFirstApp);
2.Props(属性)
class Greeting extends Component {
render() {
return (
<View>
<Text>Hello {this.props.name}</Text>
</View>
);
}
}
export default class myFirstApp extends Component {
render() {
return (
<View style={{ alignItems: 'center' }}>
<Greeting name='react!' />
<Greeting name='react-native' />
<Greeting name='android' />
</View>
)
}
}
3.State(状态)
在constructor中初始化state,然后在需要修改时调用setState方法。
constructor(props){
super(props);
this.state = {
count: 0,
}
}
doUpdateCount(){
this.setState({
count: this.state.count+1
})
}
<Text>当前计数是:{this.state.count}</Text>
<TouchableOpacity onPress={this.doUpdateCount.bind(this)} style={{padding: 5,backgroundColor: '#ccc'}}>
<Text>点我开始计数</Text>
</TouchableOpacity>
4.样式
<View>
<Text style={[styles.bigblue],{backgroundColor: '#0f0'}}>style set</Text>
<Text style={[styles.bigblue, {backgroundColor: '#00f'}]}>style set</Text>
<Text style={{color:'#f00'}}>just red</Text>
<Text style={styles.red}>just red</Text>
<Text style={styles.bigblue}>just bigblue</Text>
<Text style={[styles.bigblue, styles.red]}>bigblue, then red</Text>
<Text style={[styles.red, styles.bigblue]}>red, then bigblue</Text>
</View>
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
5.高度与宽度
(1)指定宽高
React Native中的尺寸都是无单位的,表示的是与设备像素密度无关的逻辑像素点。
<View>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 100, height: 100, backgroundColor: 'skyblue'}} />
<View style={{width: 150, height: 150, backgroundColor: 'steelblue'}} />
</View>
(2)弹性(Flex)宽高
使用flex:1来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了flex:1,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex值不一样,则谁的值更大,谁占据剩余空间的比例就更大。
组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的width和height,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的。
<View style={{flex: 1}}>
<View style={{flex: 1, backgroundColor: 'powderblue'}} />
<View style={{flex: 2, backgroundColor: 'skyblue'}} />
<View style={{flex: 3, backgroundColor: 'steelblue'}} />
</View>
(3)react native没有宽高100%的设置,所以如果需要让元素撑满屏幕,需要:
import { Dimensions, View } from 'react-native';
<View style={{width: Dimensions.get('window').width,height: Dimensions.get('window').height}} />
6.使用Flexbox布局
flexDirection
的默认值是column而不是row,flex也只能指定一个数字值。
flexDirection可以决定布局的主轴。子元素是应该沿着水平轴(row
)方向排列,还是沿着竖直轴(column
)方向排列呢?默认值是竖直轴(column)方向。justifyContent
可以决定其子元素沿着主轴的排列方式。子元素是应该靠近主轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start,center,flex-end,space-around以及space-between
。alignItems
可以决定其子元素沿着次轴(与主轴垂直的轴,比如若主轴方向为row,则次轴方向为column)的排列方式。子元素是应该靠近次轴的起始端还是末尾段分布呢?亦或应该均匀分布?对应的这些可选项有:flex-start,center,flex-end以及stretch
。
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}>
<View style={{width: 50, height: 50, backgroundColor: 'powderblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'skyblue'}} />
<View style={{width: 50, height: 50, backgroundColor: 'steelblue'}} />
</View>
7.处理文本输入
TextInput
是一个允许用户输入文本的基础组件。它有一个名为onChangeText
的属性,此属性接受一个函数,而此函数会在文本变化时被调用。另外还有一个名为onSubmitEditing
的属性,会在文本被提交后(用户按下软键盘上的提交键)调用(注意react
中的onChange
对应的是rn中的onChangeText
)。
constructor(props) {
super(props);
this.state = {text: ''};
}
render() {
return (
<View style={{padding: 10}}>
<TextInput
style={{height: 40}}
placeholder="Type here to translate!"
onChangeText={(textCont) => this.setState({text:textCont})}
/>
<Text style={{padding: 10, fontSize: 42}}>
{this.state.text.split(' ').map((word) => word && 'xhh').join()}
</Text>
</View>
);
}
8.ScrollView
import React, { Component } from 'react';
import { ScrollView, View } from 'react-native';
export default class MyScrollView extends Component {
getScrollViewList(){
let scrollViewList = [];
let colorList = ['red','green','blue','purple'];
for(let i=0;i<colorList.length;i++) {
var ViewItem = <View key={i} style={{ width: 420, height: 150, backgroundColor: colorList[i] }}></View>;
scrollViewList.push(ViewItem);
}
console.log(scrollViewList);
return scrollViewList;
}
render(){
return (
<ScrollView horizontal={true}>
{ this.getScrollViewList() }
</ScrollView>
)
}
}
如果页面内容一屏展示不完,需要滚动观看那就可以使用ScrollView
了。
9.ListView
ListView组件用于显示一个垂直的滚动列表,其中的元素之间结构近似而仅数据不同。
ListView更适于长列表数据,且元素个数可以增删。和ScrollView不同的是,ListView并不立即渲染所有元素,而是优先渲染屏幕上可见的元素。
ListView组件必须的两个属性是dataSource和renderRow。dataSource是列表的数据源,而renderRow则逐个解析数据源中的数据,然后返回一个设定好格式的组件来渲染。
rowHasChanged函数也是ListView的必需属性。这里我们只是简单的比较两行数据是否是同一个数据(===符号只比较基本类型数据的值,和引用类型的地址)来判断某行数据是否变化了。
import React, { Component } from 'react';
import { ListView, Text, View } from 'react-native';
export class ListViewBasics extends Component {
// 初始化模拟数据
constructor(props) {
super(props);
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows([
'John', 'John', 'James', 'Jimmy', 'Jackson', 'Jillian', 'Julie', 'Devin'
])
};
}
render() {
return (
<View style={{flex: 1,width: 150,height: 100,marginTop: 5, marginBottom: 5 }}>
<ListView
dataSource={this.state.dataSource}
renderRow={(myRowData) => <Text>{myRowData}</Text>}
/>
</View>
);
}
}
10.网络
import React, { Component } from 'react';
import { TouchableOpacity, Text, View } from 'react-native';
export default class FetchAjax extends Component {
constructor(){
super();
this.state = {
textDesc: 'initialText',
}
}
// 初始化模拟数据
getData(){
fetch('http://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson);
this.setState({
textDesc: responseJson.movies[0].title,
})
})
.catch((error) => {
console.error(error);
});
}
render() {
return (
<View>
<TouchableOpacity style={{ padding: 5,borderWidth:1, borderColor:'#aaa',borderRadius:4 }} onPress={this.getData.bind(this)} >
<Text>Click Get Data</Text>
</TouchableOpacity>
<Text>{this.state.textDesc}</Text>
</View>
);
}
}
11.路由Navigator
导航方法:
如果你得到了一个navigator对象的引用(译注:再次推荐仔细阅读此教程,理解如何在renderScene方法中传递navigator对象,否则直接调用会报undefined错误),则可以调用许多方法来进行导航:getCurrentRoutes()
- 获取当前栈里的路由,也就是push进来,没有pop掉的那些。jumpBack()
- 跳回之前的路由,当然前提是保留现在的,还可以再跳回来,会给你保留原样。jumpForward()
- 上一个方法不是调到之前的路由了么,用这个跳回来就好了。jumpTo(route)
- 跳转到已有的场景并且不卸载。push(route)
- 跳转到新的场景,并且将场景入栈,你可以稍后跳转过去pop()
- 跳转回去并且卸载掉当前场景replace(route)
- 用一个新的路由替换掉当前场景replaceAtIndex(route, index)
- 替换掉指定序列的路由场景replacePrevious(route)
- 替换掉之前的场景resetTo(route)
- 跳转到新的场景,并且重置整个路由栈immediatelyResetRouteStack(routeStack)
- 用新的路由数组来重置路由栈popToRoute(route)
- pop到路由指定的场景,在整个路由栈中,处于指定场景之后的场景将会被卸载。popToTop()
- pop到栈中的第一个场景,卸载掉所有的其他场景。
属性:configureScene [function]
可选的函数,用来配置场景动画和手势。会带有两个参数调用,一个是当前的路由,一个是当前的路由栈。然后它应当返回一个场景配置对象。具体有哪些可以看这个目录:node_modules/react-native/Libraries/CustomComponents/Navigator/NavigatorSceneConfigs.js
(route, routeStack) => Navigator.SceneConfigs.FloatFromRight
Navigator.SceneConfigs.PushFromRight (默认)
Navigator.SceneConfigs.FloatFromRight
Navigator.SceneConfigs.FloatFromLeft
Navigator.SceneConfigs.FloatFromBottom
Navigator.SceneConfigs.FloatFromBottomAndroid
Navigator.SceneConfigs.FadeAndroid
Navigator.SceneConfigs.HorizontalSwipeJump
Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
Navigator.SceneConfigs.VerticalUpSwipeJump
Navigator.SceneConfigs.VerticalDownSwipeJump
initialRoute [object]
定义启动时加载的路由。路由是导航栏用来识别渲染场景的一个对象。initialRoute必须是initialRouteStack中的一个路由。initialRoute默认为initialRouteStack中最后一项。initialRouteStack [object]
提供一个路由集合用来初始化。如果没有设置初始路由的话则必须设置该属性。如果没有提供该属性,它将被默认设置成一个只含有initialRoute的数组。navigationBar [node]
可选参数,提供一个在场景切换的时候保持的导航栏。navigator [object]
可选参数,提供从父导航器获得的导航器对象。onDidFocus [function]
每当导航切换完成或初始化之后,调用此回调,参数为新场景的路由。onWillFocus [function]
会在导航切换之前调用,参数为目标路由。renderScene [function]
必要参数。用来渲染指定路由的场景。调用的参数是路由和导航器。
(route, navigator) =>
<MySceneComponent title={route.title} navigator={navigator} />
sceneStyle [View#style]
将会应用在每个场景的容器上的样式。
index.android.js:
configureScene(route){
if(route.name == 'FirstPage'){
return Navigator.SceneConfigs.FloatFromBottom
}
return Navigator.SceneConfigs.FloatFromRight;
}
renderScene(router, navigator){
let Component = router.component;
switch(router.name){
case "FirstPage":
Component = FirstPage;
break;
case "SecondPage":
Component = MySecondPage;
break;
}
return <Component {...router.params} navigator={navigator} />
}
renderHead(){
return(
<View style={{height:60,position:'absolute',top:0,left:0,right:0,backgroundColor:'#666',justifyContent: 'center',alignItems: 'center',borderWidth:1,borderColor:'#ccc'}}>
<Text>
{'Navigator Bar'}
</Text>
</View>
)
}
<Navigator
navigationBar = {this.renderHead()}
initialRoute={{name: 'FirstPage'}}
configureScene={this.configureScene}
renderScene={this.renderScene.bind(this)} />
navigator.js:
import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import MySecondPage from './navigatorPage';
export default class FirstPage extends Component {
onPressButton() {
this.props.navigator.push({
component: MySecondPage,
params : {
param1 : 'param1Value'
},
type: 'Bottom'
})
console.log(this.props.navigator.getCurrentRoutes());
}
componentWillUnmount(){
console.log('FirstPage-componentWillUnmount');
}
render(){
return(
<View style={{marginTop: 60, flex:1,justifyContent: 'center',alignItems: 'center',}}>
<Text>{'first Page'}</Text>
<TouchableOpacity onPress={()=>this.onPressButton()}>
<Text>点击跳转到第二页</Text>
</TouchableOpacity>
</View>
)
}
}
navigatorPage.js:
import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import MyThirdPage from './navigatorOtherPage';
export default class MySecondPage extends Component {
onPressButton() {
this.props.navigator.push({
component: MyThirdPage,
type: 'Right'
})
console.log(this.props.param1); //param1Value
console.log(this.props.navigator.getCurrentRoutes());
}
componentWillUnmount(){
console.log('MySecondPage-componentWillUnmount');
}
render(){
return(
<View style={{marginTop: 60, flex:1,justifyContent: 'center',alignItems: 'center',}}>
<Text>{'second Page'}</Text>
<TouchableOpacity onPress={()=>this.onPressButton()}>
<Text>点击跳转到第三页</Text>
</TouchableOpacity>
</View>
)
}
}
navigatorOtherPage.js:
import React, { Component } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
import FirstPage from './navigator';
import MySecondPage from './navigatorPage';
export default class MyThirdPage extends Component {
// <TouchableOpacity onPress={()=>this.props.navigator.pop()}>
// <Text>返回到第二页</Text>
// </TouchableOpacity>
// <TouchableOpacity onPress={()=>this.props.navigator.replace({component: FirstPage})}>
// <Text>返回到第一页</Text>
// </TouchableOpacity>
// 就只执行了一次
// <TouchableOpacity onPress={()=>this.props.navigator.replaceAtIndex({component: FirstPage}, 2)}>
// <Text>返回到第一页</Text>
// </TouchableOpacity>
// <TouchableOpacity onPress={()=>this.props.navigator.replaceAtIndex({component: MySecondPage}, 2)}>
// <Text>返回到第二页</Text>
// </TouchableOpacity>
// <TouchableOpacity onPress={()=>this.props.navigator.resetTo({component: FirstPage})}>
// <Text>返回到第一页</Text>
// </TouchableOpacity>
// <TouchableOpacity onPress={()=>this.props.navigator.resetTo({component: MySecondPage})}>
// <Text>返回到第二页</Text>
// </TouchableOpacity>
// <TouchableOpacity onPress={()=>this.props.navigator.popToTop()}>
// <Text>返回到第一页</Text>
// </TouchableOpacity>
componentWillUnmount(){
console.log('MyThirdPage-componentWillUnmount');
}
render(){
return(
<View style={{marginTop: 60,flex:1,justifyContent: 'center',alignItems: 'center',}}>
<Text>{'third Page'}</Text>
<TouchableOpacity onPress={()=>this.props.navigator.replace({component: FirstPage})}>
<Text>返回到第一页</Text>
</TouchableOpacity>
</View>
)
}
}
下面是一个查询用户信息的例子,FirstPage传递id到MySecondPage,然后MySecondPage返回user信息给FirstPage。FirstPage:
import React, { Component } from 'react';
import {
View,
Navigator
} from 'react-native';
import MySecondPage from './MySecondPage';
export default class FirstPage extends Component {
constructor(props) {
super(props);
this.state = {
id: 2,
user: null,
}
}
pressButton() {
if(this.props.navigator) {
this.props.navigator.push({
name: 'MySecondPage',
component: MySecondPage,
params: {
id: this.state.id,
//从MySecondPage获取user
getUser: (myUser) => {
this.setState({
user: myUser
})
}
}
});
}
}
render() {
if(this.state.user) {
return(
<View>
<Text>用户信息: { JSON.stringify(this.state.user) }</Text>
</View>
);
}else {
return(
<View>
<TouchableOpacity onPress={this.pressButton.bind(this)}>
<Text>查询ID为{ this.state.id }的用户信息</Text>
</TouchableOpacity>
</View>
);
}
}
}
MySecondPage:
const myObj = {
1: { name: 'user1', age: 25 },
2: { name: 'user2', age: 26 }
};
import React from 'react';
import {
View,
Navigator
} from 'react-native';
import FirstPage from './FirstPage';
export default class MySecondPage extends React.Component {
constructor(props) {
super(props);
this.state = {
id: null
}
}
componentDidMount() {
//这里获取从FirstPage传递过来的参数: id
this.setState({
id: this.props.id
});
}
pressButton() {
const { navigator } = this.props;
if(this.props.getUser) {
let user = myObj[this.props.id];
this.props.getUser(user);
}
if(navigator) {
navigator.pop();
}
}
render() {
return(
<View>
<Text>获得的参数: id={ this.state.id }</Text>
<TouchableOpacity onPress={this.pressButton.bind(this)}>
<Text>点我跳回去</Text>
</TouchableOpacity>
</View>
);
}
}
下面是一个登陆页和欢迎页的例子。
MyFirstApp.js:
import React, { Component } from 'react';
import {
AppRegistry,
Text,
View,
Navigator,
TouchableOpacity,
Platform
} from 'react-native';
import Splash from './Splash';
const defaultRoute = {
component: Splash
};
export default class myFirstApp extends Component {
_renderScene(route, navigator) {
let Component = route.component;
return (
<Component {...route.params} navigator={navigator} />
);
}
_renderNavBar() {
const styles = {
title: {
flex: 1, alignItems: 'center', justifyContent: 'center'
},
button: {
flex: 1, width: 50, alignItems: 'center', justifyContent: 'center'
},
buttonText: {
fontSize: 18, color: '#FFFFFF', fontWeight: '400'
}
}
var routeMapper = {
LeftButton(route, navigator, index, navState) {
if(index > 0) {
return (
<TouchableOpacity
onPress={() => navigator.pop()}
style={styles.button}>
<Text style={styles.buttonText}>Back</Text>
</TouchableOpacity>
);
} else {
return (
<TouchableOpacity
onPress={() => navigator.pop()}
style={styles.button}>
<Text style={styles.buttonText}>Logo</Text>
</TouchableOpacity>
);
}
},
RightButton(route, navigator, index, navState) {
if(index > 0 && route.rightButton) {
return (
<TouchableOpacity
onPress={() => navigator.pop()}
style={styles.button}>
<Text style={styles.buttonText}></Text>
</TouchableOpacity>
);
} else {
return null
}
},
Title(route, navigator, index, navState) {
return (
<View style={styles.title}>
<Text style={styles.buttonText}>{route.title ? route.title : 'Splash'}</Text>
</View>
);
}
};
return (
<Navigator.NavigationBar
style={{
alignItems: 'center',
backgroundColor: '#55ACEE',
shadowOffset:{
width: 1,
height: 0.5,
},
shadowColor: '#55ACEE',
shadowOpacity: 0.8,
}}
routeMapper={routeMapper} />
)
}
render() {
return (
<View style={{height:200}}>
<Navigator
initialRoute={defaultRoute}
renderScene={this._renderScene}
sceneStyle={{paddingTop: (Platform.OS === 'android' ? 66 : 74)}}
navigationBar={this._renderNavBar()} />
</View>
);
}
}
});
AppRegistry.registerComponent('myFirstApp', () => myFirstApp);
Splash.js:
import React, { Component } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import Login from './Login';
class Splash extends Component {
_openPage() {
this.props.navigator.push({
title: 'Login',
component: Login
})
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', backgroundColor: '#FFFFFF' }}>
<Text>Splash Page</Text>
<TouchableOpacity onPress={this._openPage.bind(this)}>
<Text style={{ color: '#55ACEE' }}>Open New Page</Text>
</TouchableOpacity>
</View>
);
}
}
export default Splash;
Login.js:
import React, { Component } from 'react';
import {View, Text, TextInput, TouchableOpacity } from 'react-native';
import Welcome from './Welcome';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
name: null,
age: null,
}
}
_openPage() {
this.props.navigator.push({
component: Welcome,
params: {
name: this.state.name,
age: this.state.age,
changeMyAge: (age) => {
this.setState({ age })
}
}
})
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', backgroundColor: '#FFFFFF' }}>
<Text>Form Page</Text>
<TextInput
value={this.state.name}
onChangeText={name => this.setState({ name })}
placeholder={'Enter your name'}
style={{ height: 40, width: 200 }} />
<Text>My age: {this.state.age ? this.state.age : 'Unknown'}</Text>
<TouchableOpacity onPress={this._openPage.bind(this)}>
<Text style={{ color: '#55ACEE' }}>Update my age</Text>
</TouchableOpacity>
</View>
);
}
}
export default Login;
Welcome.js:
import React, { Component } from 'react';
import { TextInput, View, Text, TouchableOpacity } from 'react-native';
class Welcome extends Component {
_back() {
this.props.navigator.pop();
}
render() {
return (
<View style={{ flex: 1, alignItems: 'center', backgroundColor: '#FFFFFF' }}>
<Text>Welcome Page</Text>
<Text>Welcome to Navigation! {this.props.name}</Text>
<TextInput
onChangeText={age => this.props.changeMyAge(age) }
placeholder={'Enter your age:'}
style={{ height: 40, width: 200 }} />
<TouchableOpacity onPress={this._back.bind(this)}>
<Text style={{ color: '#55ACEE' }}>Save my age</Text>
</TouchableOpacity>
</View>
);
}
}
export default Welcome;
12.组件生命周期
实例化
首次实例化
getDefaultProps
getInitialState
componentWillMount
render
componentDidMount
实例化完成后的更新
getInitialState
componentWillMount
render
componentDidMount
存在期
组件已存在时的状态改变
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
销毁&清理期
componentWillUnmount
说明
生命周期共提供了10个不同的API。
1.getDefaultProps
作用于组件类,只调用一次,返回对象用于设置默认的props,对于引用值,会在实例中共享。
2.getInitialState
作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props。
3.componentWillMount
在完成首次渲染之前调用,此时仍可以修改组件的state。
4.render
必选的方法,创建虚拟DOM,该方法具有特殊的规则:
只能通过this.props和this.state访问数据
可以返回null、false或任何React组件
只能出现一个顶级组件(不能返回数组)
不能改变组件的状态
不能修改DOM的输出
5.componentDidMount
真实的DOM被渲染出来后调用,在该方法中可通过this.getDOMNode()访问到真实的DOM元素。此时已可以使用其他类库来操作这个DOM。
在服务端中,该方法不会被调用。
6.componentWillReceiveProps
组件接收到新的props时调用,并将其作为参数nextProps使用,此时可以更改组件props及state。
componentWillReceiveProps: function(nextProps) {
if (nextProps.bool) {
this.setState({
bool: true
});
}
}
7.shouldComponentUpdate
组件是否应当渲染新的props或state,返回false表示跳过后续的生命周期方法,通常不需要使用以避免出现bug。在出现应用的瓶颈时,可通过该方法进行适当的优化。
在首次渲染期间或者调用了forceUpdate方法后,该方法不会被调用
8.componentWillUpdate
接收到新的props或者state后,进行渲染之前调用,此时不允许更新props或state。
9.componentDidUpdate
完成渲染新的props或者state后调用,此时可以访问到新的DOM元素。
10.componentWillUnmount
组件被移除之前被调用,可以用于做一些清理工作,在componentDidMount方法中添加的所有任务都需要在该方法中撤销,比如创建的定时器或添加的事件监听器。
import React, { Component, PropTypes } from 'react';
import { Text, View, TouchableOpacity } from 'react-native';
export default class MyPropType extends Component {
constructor(props){
super(props);
this.state = {
stateName: this.props.myName + ',xhh',
count: 0,
}
console.log('init-constructor');
}
static propTypes = {
myName: PropTypes.string,
age: PropTypes.number,
sex: PropTypes.string.isRequired
}
static get defaultProps() {
return {
myName: "xhh",
age: 18
}
}
doUpdateCount(){
this.setState({
count: this.state.count+1
})
}
componentWillMount() {
console.log('componentWillMount');
}
componentDidMount() {
console.log('componentDidMount')
}
componentWillReceiveProps(nextProps){
console.log('componentWillReceiveProps')
}
shouldComponentUpdate(nextProps, nextState){
console.log('shouldComponentUpdate');
// return nextProps.id !== this.props.id;
if(nextState.count > 10) return false;
return true;
}
componentWillUpdate(){
console.log('componentWillUpdate');
}
componentDidUpdate(){
console.log('componentDidUpdate');
}
componentWillUnmount(){
console.log('componentWillUnmount');
}
render(){
console.log('render');
return (
<View>
<Text>姓名:{this.props.myName}</Text>
<Text>别名:{this.state.stateName}</Text>
<Text>年龄:{this.props.age}</Text>
<Text>性别:{this.props.sex}</Text>
<Text>父元素计数是:{this.state.count}</Text>
<TouchableOpacity onPress={ this.doUpdateCount.bind(this) } style={{ padding: 5,backgroundColor: '#ccc' }}>
<Text>点我开始计数</Text>
</TouchableOpacity>
<SubMyPropType count1={this.state.count} />
</View>
)
}
}
class SubMyPropType extends Component {
componentWillReceiveProps(nextProps){
console.log('subMyPropType-componentWillReceiveProps')
}
shouldComponentUpdate(nextProps, nextState){
console.log('subMyPropType-shouldComponentUpdate');
// return nextProps.id !== this.props.id;
if(nextProps.count1 > 5) return false;
return true;
}
componentWillUpdate(){
console.log('subMyPropType-componentWillUpdate');
}
componentDidUpdate(){
console.log('subMyPropType-componentDidUpdate');
}
componentWillUnmount(){
console.log('subMyPropType-componentWillUnmount');
}
render(){
console.log('subMyPropType-render');
return(
<Text>子元素计数是:{this.props.count1}</Text>
)
}
}
// init-constructor
// componentWillMount
// render
// subMyPropType-render
// componentDidMount
//子元素和父元素都在计时
// shouldComponentUpdate
// componentWillUpdate
// render
// subMyPropType-componentWillReceiveProps
// subMyPropType-shouldComponentUpdate
// subMyPropType-componentWillUpdate
// subMyPropType-render
// subMyPropType-componentDidUpdate
// componentDidUpdate
//子元素停止计时(count1 > 5)
// shouldComponentUpdate
// componentWillUpdate
// render
// subMyPropType-componentWillReceiveProps
// subMyPropType-shouldComponentUpdate
// componentDidUpdate
//父元素也停止计时
// shouldComponentUpdate
// 生命周期 调用次数 能否使用setSate()
// getDefaultProps 1(全局调用一次) 否
// getInitialState 1 否
// componentWillMount 1 是
// render >=1 否
// componentDidMount 1 是
// componentWillReceiveProps >=0 是
// shouldComponentUpdate >=0 否
// componentWillUpdate >=0 否
// componentDidUpdate >=0 否
// componentWillUnmount 1 否
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。