引言:生命周期自从出现hook之后,其空间越来越小。
1.生命周期仅限于 类组件。
2. render中不能改变state中数据
3.三种形式可以调用render
- state数据更改,无论render中有无用到该数据
- 使用了this.forceUpdate()方法
- 组件接收到的 props发生了改变
另外父组件只要发生了render,子组件的render肯定会执行
import React, { Component } from 'react'
export default class App13 extends Component {
state = {
num: 0
}
handlerClick = () => {
this.setState({
num: this.state.num + 1
})
}
render() {
console.log("render")
return (
<div>
{this.state.num}
<button onClick={this.handlerClick}>clickme</button>
<App14 />
</div>
)
}
}
class App14 extends Component {
render() {
console.log("appp14render")
return (
<div>
<h1>hello</h1>
</div>
)
}
}
运行结果如下:
4. componentDidUpdate 执行
componentDidUpdate() {
console.log('componentDidUpdate')
}
5. setState是异步的
使用该语法时,后面的 setState() 不要依赖于前面的 setState() ,可以多次调用 setState() ,只会触发一次重新渲染
handlerClick = () => {
this.setState({
num: this.state.num + 1,
})
this.setState({
num: this.state.num + 1,
})
this.setState({
num: this.state.num + 2,
})
this.setState({
num: this.state.num + 1,
})
console.log(this.state.num)
}
该段代码运行结果:打印1(前提是num为0)。页面中num也是1
6. setState第二个参数:state: 保证是最新的state,上一次的state
handlerClick = () => {
this.setState((state) => ({ num: state.num + 1}))
this.setState((state) => ({ num: state.num + 1 }))
this.setState((state) => ({ num: state.num + 1 }))
this.setState((state) => ({ num: state.num + 1 }))
this.setState((state) => ({ num: state.num + 1 }),
() => {
console.log(this.state.num)
}
)
}
该段代码运行结果:打印5(前提是num为0)。页面中num也是5
7.避免不必要的渲染
- 组件更新机制:父组件更新会引起子组件也被更新,这种思路很清晰
- 问题:子组件没有任何变化时也会重新渲染
- 如何避免不必要的重新渲染呢?
- 解决方式:使用钩子函数 shouldComponentUpdate(nextProps, nextState)
- 作用:通过返回值决定该组件是否重新渲染,返回 true 表示重新渲染,false 表示不重新渲染
- 触发时机:更新阶段的钩子函数,组件重新渲染前执行 (shouldComponentUpdate --> render)
state:
class App extends Component {
shouldComponentUpdate(nextProps, nextState) {
return nextState.number !== this.state.number
}
render() {…}
}
prop:
class App extends Component {
shouldComponentUpdate(nextProps, nextState) {
return nextProps.number !== this.props.number
}
render() {…}
}
8.纯组件
- 纯组件:PureComponent 与 React.Component 功能相似
- 区别:PureComponent 内部自动实现了 shouldComponentUpdate 钩子,不需要手动比较
- 原理:纯组件内部通过分别 对比 前后两次 props 和 state 的值,来决定是否重新渲染组件
- 对于值类型来说:比较两个值是否相同(直接赋值即可,没有坑)
- 对于引用类型来说:只比较对象的引用(地址)是否相同
state 或 props 中属性值为引用类型时,应该创建新数据,不要直接修改原数据!
否则,通过对比,发现没变化。就不渲染了。这行不通的。
但是,如果这样子做了,如下代码:即使number值没有变化,依然要渲染。
有点类似宁可错杀,也不放过的感觉。
const newObj = { ...this.state.obj, number: Math.floor(Math.random() * 3) }
this.setState(() => {
return {
obj: newObj
}
})
// 错误演示:直接修改原始对象中属性的值
const newObj = this.state.obj
newObj.number = Math.floor(Math.random() * 3)
console.log(newObj.number)
this.setState(() => {
return {
obj: newObj
}
})