文章目录
在React中,生命周期钩子函数主要是针对于有状态的组件。React从v16.3之后的生命周期与之前的不同,废弃
componentWillMount
componentWillReceiveProps
componentWillUpdate
三个钩子函数,添加了新的getDerivedStateFromProps
getSnapshotBeforeUpdate
等钩子函数
1.constructor()
- 构造函数,在创建组件时调用一次。
- 常用来将传递的
props
指向this
示例对象、初始化状态对象。 - 这是es6新特性class提供的方法。
constructor(props){
super(); //this.props = props;
this.state = {number:0,users:[]}; //初始化默认的状态对象
}
2.componentWillMount()废弃
- 组件即将被渲染到页面之前触发。
- 此时可以进行开启定时器、向服务器发送请求等操作
- React从v16.3开始废弃
3.componentWillReceiveProps()废弃
- 组件接受属性时触发。
- React从v16.3开始废弃
4. componentWillUpdate()废弃
- 组件将要更新时触发。
- 接受
nextProps
,nextState
两个参数 - React从v16.3开始废弃
componentWillUpdate(nextProps, nextState){}
5.static getDerivedStateFromProps()废弃
- 接收父组件传递过来的
props
和组件之前的状态
,返回一个对象来更新 state
或者返回 null 来表示接收到的 props 没有变化,不需要更新 state - 将父组件传递过来的 props
映射
到子组件的 state 上面,这样组件内部就不用再通过 this.props.xxx 获取属性值了,统一通过 this.state.xxx 获取。 - 映射就相当于拷贝了一份父组件传过来的 props ,作为子组件自己的状态。注意:子组件通过 setState 更新自身状态时,不会改变父组件的 props
- getDerivedStateFromProps 是一个静态函数,不能使用this, 也就是只能作一些
无副作用
的操作 - 配合
componentDidUpdate()
替代componentWillReceiveProps
的全部用法 - 新的生命周期函数
// nextProps——新的属性对象 prevState——旧的状态对象
static getDerivedStateFromProps(nextprops, state) {
console.log('props',nextprops);
// 返回一个对象来更新 state 或者返回 null 来表示接收到的 props 不需要更新 state
if (nextprops.age !== state.age) {
console.log("更新吧");
return {
age: nextprops.age,
// 注意:这里不需要把组件自身的状态也放进来
};
}
return null;
}
6.render()
- 只负责生成和返回虚拟DOM元素,而实际的DOM操作(如插入、更新和删除节点)是由React的底层引擎来完成的
render()
方法必须返回- 注意不能在
render
修改state
,会引起死循环。 - 并不是一次
setState
会触发一次render
,React
可能会合并操作,再一次性进行render
。
render() {
return (
<div>
<p>{this.state.number}</p>
</div>
)
}
render
方法在组件的生命周期中运行时有两个主要阶段:
- 初次渲染(Initial Render):当组件首次被插入到
DOM
中时,render
方法会被调用。这是React组件生命周期中的第一个步骤,用于确定和生成组件的初始DOM结构。在初次渲染期间,render
方法会根据组件的props
和state
生成相应的虚拟DOM(VDOM)
元素。 - 后续重渲染(Subsequent Render):当组件的
props
或state
发生变化时,React
会重新调用render
方法来生成新的虚拟DOM
元素。React
会通过比较新旧虚拟DOM树,使用diff
算法来确定最小节点集合,然后只更新这些节点,以最小化DOM操作。这种方式被称为“虚拟DOM diffing
”,能够显著提高性能并减少不必要的DOM操作。
7.componentDidMount()
- 在组件挂载后 (插入DOM树后) 立即调用
- 此时页面中有了真正的DOM的元素,可以进行DOM相关的操作
- 发送网络请求、启用事件监听方法
- 并且可以在 此钩子函数里直接调用
setState()
componentDidMount() {
this.setState({name:'重新触发render'});
}
8.shouldComponentUpdate()
- 在组件更新之前调用。组件首次渲染时并不会触发
- 可以控制组件是否进行更新, 返回true时组件更新, 返回false则不更新
- 该钩子函数可以接收到两个参数,新的属性和状态
- 可以使用内置
PureComponent
组件替代
shouldComponentUpdate(newProps, newState) {
if (newProps.number < 5) return true;
return false
}
9.getSnapshotBeforeUpdate()废弃
getSnapshotBeforeUpdate()
在最近一次的渲染输出被提交之前调用。被调用于render
之后、更新DOM
和refs
之前。- 接收父组件传递过来的 props 和组件之前的状态
- 在 DOM 真正更新之前捕获一些信息(例如滚动位置),此生命周期返回的任何值都会作为参数传递给
componentDidUpdate()
。如不需要传递任何值,那么请返回null
- 必须和
componentDidUpdate
一起使用,否则会报错 - 配合
componentDidUpdate
, 可以覆盖componentWillUpdate
的所有用法 - 新的生命周期函数
getSnapshotBeforeUpdate(prevProps, prevState) {
// 返回更新内容的高度 300px
return this.wrapper.current.scrollHeight;
}
10.componentDidUpdate()
- 在更新后会被立即调用。首次渲染不会执行
- 包含三个参数,
prevProps
、prevState
。如果组件实现了getSnapshotBeforeUpdate()
,第三个snapshot
参数传递 - 页面中产生了新的DOM的元素,可以进行DOM操作
componentDidUpdate(prevProps, prevState, prevScrollHeight) {
this.wrapper.current.scrollTop =
this.wrapper.current.scrollTop +
(this.wrapper.current.scrollHeight - prevScrollHeight);
}
11.componentWillUnmount()
- 在组件即将被卸载或销毁时进行调用。
- 此生命周期是
取消网络请求
、移除监听事件
、清理 DOM 元素
、清理定时器
等操作的好时机
componentWillUnmount(){
console.log('SubCounter componentWillUnmount');
}