生命周期函数
实例化阶段(图中上框部分),存在阶段(图中左框部分),销毁阶段(图中右框部分)
实例化阶段
开发中,常用的就是实例化阶段,因为该阶段是组件的构建,展示阶段
getDefaultProps:
该函数用于初始化一些默认的属性,开发中,通常将一些固定不变的值放在该函数内进行初始化,
比如url。可以利用this.props.XXX 来获取该属性值。由于被初始化后,以后就不会再调用
getDefaultProps函数,所以不能对props修改,也就是pros是只读属性的,只可由其他组件调用它时再外部进行修改。
getInitialState:
该函数用于对组件的一些状态进行初始化,该状态是随时变化的(也就是说该函数会被多次调用),
比如ListView的datasource,rowData等等,同样的,可以通过this.state.XXX获取该属性值,
同时可以对该值进行修改,通过this.setState修改。该函数不同于getDefaultProps,在以后的过程中,会再次调用,所以可以将控制控件状态的一些变量放在这里初始化,比如控件上显示的文字,可以通过this.state来获取值,通过this.setState来修改state值。注意:一旦调用了this.setState方法,组件一定会调用render方法,对组件进行再次渲染,不过,React框架会根据DOM的状态自动判断是否需要真正渲染。如:
this.setState({
age:11,
name:'哈哈'
});
componentWillMount:
该函数类似于iOS中的VillWillAppear,在组件即将加载在视图上调用。
render:
该函数组件必有的,通过返回JSX或其他组件来构成DOM,换言之,就是组件的核心渲染过程。
componentDidMount:
在调用了render方法,组件加载成功并被成功渲染出来之后,所要执行的后续操作,一般都会在这个函数中进行,比如经常要面对的网络请求等加载数据操作。---因为UI已经成功渲染,而且这里面是异步的,所以放在这个函数进行数据的请求等复杂的操作,不会出现UI错误
constructor(props) {
super(props);
this.state = {
clickText: "开始点击按钮",
count: 1,
detailContent: true
}
}
...
clickButton(){
const { count } = this.state;
this.setState({
clickText: "我点击了按钮",
count: count + 1,
detailContent: false
})
}
render() {
console.log("render1111");
return (
<View style={styles.container}>
<Text>欢迎来到首页</Text>
<TouchableOpacity
onPress={() => Actions.notice()}
>
<Text>跳转到公告页</Text>
</TouchableOpacity>
<Text style={{color: 'blue', fontSize: 40}}>{this.state.count}</Text>
<TouchableOpacity
style={styles.button}
onPress={() => this.clickButton()}
>
<Text>{this.state.clickText}</Text>
</TouchableOpacity>
<HomeDetails detailContent={this.state.detailContent}/>
</View>
)
}
存在阶段
componentWillReceiveProps:
指父元素对组件的props或state进行了修改
shouldComponentUpdate:
常用于优化---一般用于优化,可以返回false或true来控制是否进行渲染(true 的话进行下2步操作,false不会进行下去)
componentWillUpdate:
组件更新时调用
componentDidUpdate:
组件更新完毕时调用
shouldComponentUpdate(nextProps, nextState){
console.log(this.state.detailContent,'detailContent');
if (this.state.count !== nextState.count) {
console.log("shouldComponentUpdate1111---组件需要更新");
return true;
}
return false;
}
componentWillUpdate(){
console.log("componentWillUpdate1111---组件将要更新");
}
componentDidUpdate(){
console.log("componentDidUpdate1111---组件更新完毕");
}
// 在子组件中对父元素props或state的改变进行监听进行相应的操作
componentWillReceiveProps(nextProps){
console.log(this.props.detailContent,'this--->>componentWillReceiveProps');
console.log(nextProps.detailContent,'next--->>componentWillReceiveProps')
}
// componentWillReceiveProps -> 改变后执行父组件中 shouldComponentUpdate -> componentWillUpdate -> componentDidUpdate
销毁阶段
componentWillUnmount:
通常做一些清理内容 如:定时器清除等等善后操作
示例
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
TouchableOpacity,
View
} from 'react-native';
//ES5写法 ES5写法和ES6稍有不同
var LifeDate = React.createClass({
getDefaultProps(){ //初始化一些不可以修改的值,初始化完毕后将不会再次调用,可以通过this.props来获取初始化后的值,不可以修改
return{
age:22
};
},
getInitialState(){ //初始化一些可以修改的值,会多次调用,可以通过this.state来获取值,通过this.setState来修改修改值
return {
isGoodPerson:true,
content: '我是人'
};
},
componentWillMount(){
return{
//相当于iOS中viewWillAppear
};
},
componentDidMount(){
return{
//相当于iOS中的viewDidLoad 可以在这里做一些复杂操作,如网络请求数据
};
},
render() {
return (
<View ref="topView" style={styles.container}>
<TouchableOpacity onPress = {() =>this.dealWithState(this.state.isGoodPerson)}>
<View style={styles.innerViewStyle}>
<Text>{this.state.content}</Text>
<Text>{this.props.age}</Text>
</View>
</TouchableOpacity>
</View>
);
},
dealWithState: function(data:Boolean){
var isGoodPerson,content;
if(data){
isGoodPerson = false,
content = '不好呀'
}else{
isGoodPerson = true,
content = '你好呀'
}
//更新状态机
this.setState({
isGoodPerson: isGoodPerson,
content: content
});
//拿到View
this.refs.topView
}
});
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
innerViewStyle: {
backgroundColor: 'red'
}
});
AppRegistry.registerComponent('Project', () => LifeDate);
知识点
this.state:开发中,组件肯定要与用户进行交互,React的一大创新就是将组件看成了一个状态机,一开始有一个初始状态,然后用户交互,导致状态变化,从而触发重新渲染UI
1、当用户点击组件,导致状态变化,this.setSate方法就修改状态值,每次修改以后,会自动调用this.render方法,再次渲染组件
2、可以把组件看成一个状态机,根据不同的status有不同的UI展示,只要使用setState改变状态值,根据diff算法算出有差值后,就会执行ReactDom的render方法,重新渲染界面
3、由于this.props和this.state都用于描述组件的特性,可能会产生混淆,一个简单的区分方法就是---this.props表示那些一旦定义,就不再更改的特性,而this.state是会随着用户交互而产生改变的特性获取真实的Dom节点
1、在React Native中,组件并不是真实的DOM节点,而是存在于内存中的一种数据结构,叫虚拟DOM
2、只有当它插入文档后,才会变成真实的DOM
3、根据React的设计,所有DOM变动,都现在虚拟DOM上发生,然后再将实际发生变动的部分,反映在真实DOM上,这种算法叫做DOM diff,它可以极大提高网页的性能表现。
4、有时需要从组建获取真实DOM节点,这时就需要到ref属性
DOM diff算法
Web界面由DOM树来构成,当其中某一部分发生变化时,其实就是对应的某个DOM节点发生了变化,在React中,构建UI界面的思路是由当前状态决定界面,前后两个状态就对应两套界面,然后由React来比较两个界面的区别,这就需要对DOM树进行Diff算法分析
示例代码
// index.js
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet,
TouchableOpacity
} from 'react-native';
import {Actions} from 'react-native-router-flux';
import HomeDetails from './HomeDetails';
export default class Home extends Component {
constructor(props) {
super(props);
this.state = {
clickText: "开始点击按钮",
count: 1,
detailContent: true
}
}
componentWillMount() {
console.log("componentWillMount1111");
}
shouldComponentUpdate(nextProps, nextState){
console.log(this.state.detailContent,'detailContent');
if (this.state.count !== nextState.count) {
console.log("shouldComponentUpdate1111---组件需要更新");
return true;
}
return false;
}
componentWillUpdate(){
console.log("componentWillUpdate1111---组件将要更新");
}
componentDidUpdate(){
console.log("componentDidUpdate1111---组件更新完毕");
}
componentDidMount() {
console.log("componentDidMount1111");
}
componentWillUnmount() {
console.log("componentWillUnmount1111");
}
clickButton(){
const { count } = this.state;
this.setState({
clickText: "我点击了按钮",
count: count + 1,
detailContent: false
})
}
render() {
console.log("render1111");
return (
<View style={styles.container}>
<Text>欢迎来到首页</Text>
<TouchableOpacity
onPress={() => Actions.notice()}
>
<Text>跳转到公告页</Text>
</TouchableOpacity>
<Text style={{color: 'blue', fontSize: 40}}>{this.state.count}</Text>
<TouchableOpacity
style={styles.button}
onPress={() => this.clickButton()}
>
<Text>{this.state.clickText}</Text>
</TouchableOpacity>
<HomeDetails detailContent={this.state.detailContent}/>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center"
},
button: {
width: 250,
height: 60,
backgroundColor: 'red',
borderRadius: 10,
alignItems: 'center',
justifyContent: 'center'
}
});
//子组件HomeDtails.js
import React, {Component} from 'react';
import {
View,
Text,
StyleSheet
} from 'react-native';
export default class HomeDetails extends Component {
constructor(props) {
super(props);
this.state = {}
}
componentWillMount() {
}
componentWillReceiveProps(nextProps){
console.log(this.props.detailContent,'this--->>componentWillReceiveProps');
console.log(nextProps.detailContent,'next--->>componentWillReceiveProps')
}
componentDidMount() {
}
componentWillUnmount() {
}
render() {
return (
<View style={styles.container}>
<Text>欢迎HomeDetails</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center"
}
});