react-native组件生命周期
对react-native生命周期进行总结生命周期调用次数能否使用setState()getDefaultProps1(全局调用一次)否getInitialState1否componentWillMount1是render>=1否componentDidMount1是componentWillReceiveProps>=0是shou..
react-native的组件生命周期总结:

| 生命周期 | 调用次数 | 能否使用setState() |
|---|---|---|
| getDefaultProps | 1(全局调用一次) | 否 |
| getInitialState | 1 | 否 |
| componentWillMount | 1 | 是 |
| render | >=1 | 否 |
| componentDidMount | 1 | 是 |
| componentWillReceiveProps | >=0 | 是 |
| shouldComponentUpdate | >=0 | 否 |
| componentWillUpdate | >=0 | 否 |
| componentDidUpdate | >=0 | 否 |
| componentWillUnmount | 1 | 否 |
注意:当调用this.setState时就会调用组件的render方法,但React框架会根据dom节点状态确定是否需要重新渲染。
this.setState
this.setState用法
this.setState(arg1,arg2),arg1可以是对象也可以是函数(必需),arg2是一个回调函数,在此函数中可以获取被setState更改后的state值,arg2可为空。
当arg1是对象时的写法:
this.setState({
key : val
},()=>{
console.log(this.state.key);
})
当arg1是函数时的写法:
//第一种写法(在更改state值之前执行一些操作)
this.setState(
(prevState,props)=>{
console.log(prevState);
return { key : prevState.key+props.val };
},()=>{
console.log(this.state.key);
}
);
//第二种写法
this.setState(
(prevState,props)=>({
key : prevState.key+props.val
}),()=>{
console.log(this.state.key);
}
);
this.setState的使用场景
当通过this.state.key = val直接修改state值时,虽然可以更改state值,但是不会触发re-render对组件进行重新渲染,使用this.setState()更改state数据值,会触发re-render,组件会根据diff算法判断是否需要重新渲染。
this.setState()的异步更新
this.setState()修改state值可能是异步更新,React 为了优化性能,有可能会将多个 setState() 调用合并为一次更新。
例如:
function incrementMultiple() {
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
this.setState({count: this.state.count + 1});
}
函数incrementMultiple()执行之后,count的值没有增加3,而是增加了1,因为setState每次执行时依赖的值都是当前状态下的count,也就是三次更新操作所依赖的count值是相同的,setState将三次更新操作合并成了一个,所以函数执行完count值只增加了1。如果想要实现count值增加3的效果,setState在执行时所依赖的count值需要是前一个更新状态结束后的count值,即:
function incrementMultiple() {
this.setState((prevState)=>({count: prevState.count + 1}));
this.setState((prevState)=>({count: prevState.count + 1}));
this.setState((prevState)=>({count: prevState.count + 1}));
}
在React控制的事件处理程序中,this.setState()更改state值不是同步更新的:

在 React 的 setState 函数实现中,会根据一个变量 isBatchingUpdates 判断是直接更新 this.state 还是放到队列中回头再说,而 isBatchingUpdates 默认是 false,也就表示 setState 会同步更新 this.state,但是有一个函数 batchedUpdates,这个函数会把isBatchingUpdates 修改为 true,而当 React 在调用事件处理函数之前就会调用这个 batchedUpdates,造成的后果,就是由 React 控制的事件处理过程 setState 不会同步更新 this.state。(原文)
组件的生命周期分为三个阶段:
一、实例化阶段:
getDefaultprops():此方法在全局过程中只调用一次,在初始化时为组件设置初始值,可通过this.props进行访问,此方法在对象创建之前执行,因此不能在方法内对props进行修改,只能通过外部组件调用this.props进行修改,任何由getDefaultProps()方法返回的对象在组件类中共享,而不是复制。
var App = React.createClass({
getDefaultProps : function () {
return {
title : 'Hello World'
};
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
ReactDOM.render(
<MyTitle />,
document.body
);
React通过PropTypes提供了一种验证props的方式,当属性验证不通过时会报错。
var App = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
},
render: function() {
return <h1> {this.props.title} </h1>;
}
});
常用的PropTypes:
// 布尔值
React.PropTypes.bool
// 数值
React.PropTypes.number
// 字符串
React.PropTypes.string
// 函数
React.PropTypes.func
// 数组
React.PropTypes.array
// 对象
React.PropTypes.object
// 数值、字符串、DOM 元素及包含这些类型的数组
React.PropTypes.node
// React 元素
React.PropTypes.element
// 对象实例
React.PropTypes.instanceOf(Message)
// 数组包含的值之一
React.PropTypes.oneOf(['News' 'Photos'])
// 数组包含的类型之一
React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.number,
React.PropTypes.instanceOf(Message)
])
// 数值数组
React.PropTypes.arrayOf(React.PropTypes.number)
// 对象的属性值为数值类型
React.PropTypes.objectOf(React.PropTypes.number)
// 组合类型
React.PropTypes.shape({
React.PropTypes.string
React.PropTypes.number
})
// 任何类型,必填
React.PropTypes.any.isRequired
// 自定义规则
customProp: function(props propName componentName) {
if (!/matchme/.test(props[propName])) {
return new Error('Validation failed!');
}
}
getInitialState():此方法对组件状态进行初始化,可通过this.state进行访问,此方法与React.crea-teClass共同使用,是ES5的写法,而在ES6规范中直接通过构造函数constructor对this.state进行赋值初始化(推荐ES6写法)。
//ES5 规范
var App = React.createClass({
propTypes: {
title: PropTypes.string.isRequired
},
getInitialState () {
return {
items: []
};
}
});
//ES6 规范
class App extends React.Component {
constructor () {
super()
this.state = {
items: []
}
}
});
通过getInitialState()实现反模式(通过this.props初始化state):
//反模式
getDefaultProps(){
return {
data: new Date()
}
},
getInitialState(){
return {
day: this.props.date - new Date()
}
},
render(){
return <div>Day:{this.state.day}</div>
}
通过this.props来初始化state值并且后续不需要改变值时可以使用反模式,否则为了保证state值与派生出它的this.props同步,需要使用正确模式。
//正确模式
getDefaultProps(){
return {
day:new Date()
}
},
render{
let day=this.props.day-new Date();
return <div>Day:{day}</div>
}
componentWillMount():此方法在render之前调用,可以调用this.setState()在渲染前对组件state进行修改。此方法在react v16.3 版本发布后被去掉了,过度方案是在被去掉的函数前加UNSAFE_前缀继续使用。官网建议在constructor()中初始换state,异步拉取数据和定时器建议在component-DidMount()中实现。
render():此方法会生成一个虚拟DOM(高效),表示组件的输出。在此方法中不可调用this.setState()进行修改。
此方法需要满足以下几点:
(1)只能通过this.props和this.state访问数据。
(2)可以返回null、false和任意React组件。
(3)只能返回一个顶级组件,不能返回一组元素。
(4)不能改变组件状态。
(5)不能修改DOM输出。
componentDidMount():此方法在组件渲染后调用一次,此方法在调用之前,已经渲染出真实的DOM,在此方法中可通过ReactDOM.findDOMNode()方法和refs属性获取到真实的DOM节点。
//ReactDOM.findDOMNode()
import ReactDOM from 'react-dom';
ReactDOM.findDOMNode(ReactComponent);
render(){
//your view code
}
componentDidMount(){
let dom=ReactDOM.findDOMNode(this);
}
//refs属性
render(){
return <canvas ref='main'></canvas>
}
componentDidMount(){
let main=this.refs.main;
}
二、存在阶段
componentWillReceiveProps():此方法当组件接收新的props时执行,但此方法在react v16.3 版本发布后被去掉了,过度方案是在被去掉的函数前加UNSAFE_前缀继续使用。在此方法中可以调用this.setState()对组件state值进行修改。
componentWillReceiveProps(newProps){
if(newProps.title!==undefined){
this.setState({
title : newProps.title
});
}
}
shouldComponentUpdate():此方法当组件的props或者state发生变化时执行(初始化时不执行),返回一个bool值,当返回值为true时,componentWillUpdate()、render()和component-DidUpdate()将会被调用,也可以通过返回false阻止组件重新渲染。
componentWillUpdate():当shouldComponentUpdate()返回值为true时调用此方法,在render()方法之前执行,不可以在此方法中调用this.setState()方法改变组件state值,当此方法被调用后会自动将newState和newProps设置到this.state和this.props中。此方法在react v16.3 版本发布后被去掉了,过度方案是在被去掉的函数前加UNSAFE_前缀继续使用。
componentDidUpdate():当shouldComponentUpdate()返回值为true时调用此方法,在render()方法之后执行,不可以在此方法中调用this.setState()方法改变组件state值。
三、销毁阶段
componentWillUnMount():此方法在组件卸载之前调用,可以进行清理工作,如移除计时器等。
在componentDidMount()中增加的方法在卸载前都需要在componentWillUnMount()中进行清理。
当组件再次被加载时会再依次调用以下方法:
getInitialState()
componentWillMount()
render()
componentDidMount()
更多推荐

所有评论(0)