组件生命周期的三个阶段
Mounting(加载阶段)
Updating(更新阶段)
Unmounting(卸载阶段)
旧的生命周期
Mounting(加载阶段:涉及6个钩子函数)
constructor()
加载的时候调用一次,可以初始化state
getDefaultProps()
设置默认的props,也可以用dufaultProps设置组件的默认属性。
1、如果是extend
方式创建的组件,不可以
用getDefaultProps
设置默认的props值,放在类名.defaultProps = {}中
class PreDes extends React.Component {
static defaultProps = {
datatext:"sssssss"
}
render(){
return ( {this.props.datatext } )
}
}
// 或者
PreDes.defaultProps = {
datatext:"sssssss"
}
export default PreDes;
2、在React.createClass中, getDefaultProps属性是一个返回Object来创建初始props的函数。
import React from 'react';
const Contacts = React.createClass({
getDefaultProps() {
return {
datatext:"sssssss"
};
},
render() {
return ( {this.props. datatext }
}
}
});
export default Contacts;
getInitialState()
初始化state,可以直接在constructor中定义this.state或者在class声明state。
在class中该方法已经废弃
下面两种写法与react没有关系,是es6支持的语法
实例属性的新写法
state={
newAddress: 'xxxxx',
}
// 或者
constructor(props){
super(props);
this.state={
newAddress: this.props.address,
}
}
getInitialState()主要是在类组件中来进行初始化state的作用。
import React from 'react';
const Contacts = React.createClass({
getInitialState() {
return {
datatext:"sssssss"
};
},
render() {
return ( {this.state.datatext }
}
}
});
export default Contacts;
componentWillMount()
组件加载时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state
render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行
componentDidMount()
组件渲染之后调用,只调用一次
Updating(更新阶段:涉及5个钩子函数)
componentWillReceiveProps(nextProps)
组件加载时不调用,组件接受新的props时调用
在这个回调函数里面,你可以根据属性的变化,通过调用this.setState()来更新你的组件状态或者是触发子组件内的某些方法,旧的属性还是可以通过this.props来获取,这里调用更新状态是安全的,并不会触发额外的render调用
在这里我们可以比较两个props从而对本组件的state作出安全的变更。
如果在这个方法中调用了一个方法,而这个方法中使用了this.props中的属性,你会发现数据并没有改变
componentWillReceiveProps(nextProps){
//componentWillReceiveProps方法中第一个参数代表即将传入的新的Props
if (this.props.sharecard_show !== nextProps.sharecard_show){
//在这里我们仍可以通过this.props来获取旧的外部状态
//通过新旧状态的对比,来决定是否进行其他方法
if (nextProps.sharecard_show){
this.handelConsole();
}
}
}
handelConsole = () => {
console.log(this.props.sharecard_show)
// 这里不是最新的props。
}
shouldComponentUpdate(nextProps, nextState)
组件接收到新的props或者state时调用,return true就会更新dom(使用diff算法更新),return false能阻止更新(不调用render)
componentWillUpdata(nextProps, nextState)
组件加载时不调用,只有在组件将要更新时才调用,此时可以修改state
render()
react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行
componentDidUpdate(prevProps, prevState, snapshot)
组件加载时不调用,组件更新完成后调用,因此在 componentDidUpdate 中可以在组件更新的时候,对 DOM 进行一些操作,同时这个方法有三个参数,可以通过参数比较比如 props ,能够判断是否需要网络请求新的数据等,比如官方文档给的示例如下:
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.userID !== prevProps.userID) {
this.fetchData(this.props.userID);
}
}
旧生命周期总结
Unmounting(卸载阶段:涉及1个钩子函数)
componentWillUnmount()
组件渲染之后调用,只调用一次
React新增的生命周期
弃用:
- componentWillMount、
- componentWillReceiveProps,
- componentWillUpdate
新增:
- getDerivedStateFromProps、
- getSnapshotBeforeUpdate
来代替弃用的三个钩子函数。
React16并没有删除这三个钩子函数,但是不能和新增的钩子函数(getDerivedStateFromProps、getSnapshotBeforeUpdate)混用,React17将会删除componentWillMount、componentWillReceiveProps,componentWillUpdate
新增了对错误的处理(componentDidCatch)
getDerivedStateFromProps(nextProps, prevState)
class ExampleComponent extends React.Component{
state = {
isSuccess: false,
};
componentWillReceiveProps(nextProps) {
if (this.props.currentRow !== nextProps.currentRow) {
this.setState({
isSuccess:true
});
}
// 在这里进行异步操作或者更新状态
this.setState({
type: props.type,
});
this._doAsyncOperation();
}
}
老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数。
当外部多个属性在很短的时间间隔之内多次变化,就会导致componentWillReceiveProps被多次调用。这个调用并不会被合并,如果这次内容都会触发异步请求,那么可能会导致多个异步请求阻塞。
尽管写的代码本身并没有问题,但componentWillReceiveProps生命周期通常会被错误地用于解决问题。因此,该方法将被弃用。
该方法是一个静态方法,与一般的类方法的区别在于它不能访问 this 关键字,还有就是方法前面有个 static 修饰符。但是有一个问题,既然访问不到 this 了,那还怎么用 this.setState 来更新状态呢?答案是,“压根就不需要用这个方法了”,你只需要返回新的状态就行了,直接 return 出去,不需要用方法去设置。如果不需要更新状态,返回 null 就行了,此外,返回值的机制和使用 setState 的机制是类似的 —— 你只需要返回发生改变的那部分状态,其他的值会保留。
class ExampleComponent extends React.Component{
state = {
isSuccess: false,
};
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.currentRow !== prevState.lastRow) {
return {
isSuccess:true,
};
}
return null;
}
getSnapshotBeforeUpdate(prevProps, prevState)
这个新更新代替componentWillUpdate。
常见的 componentWillUpdate 的用例是在组件更新前,读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理。
这两者的区别在于:
- 在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在
componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。 - getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。
此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。
参考dome: getSnapshotBeforeUpdate案例
参考文章:React新生命周期--getDerivedStateFromProps、getSnapshotBeforeUpdate