我们之前写的react PureComponent讲述了 PureComponent 组件优化特性的强大功能
还有就是 shouldComponentUpdate 生命周期的一个解决方案
那么呢 今天我们要说另一个 也是类似于组件性能优化的新特性
打开我们的react项目
在src下的components创建一个组件
例如 我这里叫 dom.jsx
参考代码如下
import React from "react";
export default class record extends React.Component{
constructor(props){
super(props);
this.state = {
cont: 0,
}
}
componentDidMount = () => {
this.myTarget = setInterval(()=>{
this.setState({
cont: 1
});
}, 1000);
}
render(){
console.log("组件被重写渲染");
return (
<div className="App">
{ this.state.cont }
</div>
)
}
}
然后 在App根组件中引入这个组件
我们可以看到 我们这个组件在componentDidMount生命周期中定义了一个定时器 每秒将响应式数据cont赋一次值
但是 既然都是1 那是不是 render 渲染一次就够啦?
因为值都是一样的
我们运行项目
可以看到 虽然我们赋值的都是 1 但是 它相当于我们每次调用setState render就会重新挂一次界面
那么 我们按之前学的解决方案就是 将 React.Component 改成 React.PureComponent
这样 就不会每次更改 就算值相同都一直重新渲染界面了
还有一种办法 就是将组件代码改成这样
import React from "react";
export default class record extends React.Component{
constructor(props){
super(props);
this.state = {
cont: 0,
}
}
shouldComponentUpdate = (props,state) => {
return state.cont !== this.state.cont;
}
componentDidMount = () => {
this.myTarget = setInterval(()=>{
this.setState({
cont: 1
});
}, 1000);
}
render(){
console.log("组件被重写渲染");
return (
<div className="App">
{ this.state.cont }
</div>
)
}
}
我们知道 修改组件响应式数据 会触发的生命周期是 shouldComponentUpdate componentWillUpdate render componentDidUpdate
而 其中 shouldComponentUpdate 中 可以返回一个值 类型为 true/false 一点返回false 在shouldComponentUpdate后执行的生命周期都不会执行
shouldComponentUpdate 接收两个行参 第一个 是 父组件传过来的值 第二个是本组件的state
需要注意的是 shouldComponentUpdate接回来的这个state中的值 是更改之前的
那么 我们就完全可以用shouldComponentUpdate接到的state和组件this中的state去做比较 判断这次有没有改变
这样 我们就相当于写了个条件 如果 state 和 this.state中的cont不一样 那就是true 允许后面的生命周期执行 否则 直接返回false 后面的生命周期就不会执行 包括render
我们在components创建一个dom1.jsx
参考代码如下
import React from "react"
const Dom = () => {
console.log("Dom1组件被重新渲染");
return (
<div>
子组件
</div>
);
};
export default Dom;
然后 我们将dom.jsx代码更改如下
import React from "react";
import Dom1 from "./dom1";
export default class record extends React.Component{
constructor(props){
super(props);
this.state = {
cont: 0,
}
}
shouldComponentUpdate = (props,state) => {
return state.cont !== this.state.cont;
}
componentDidMount = () => {
this.myTarget = setInterval(()=>{
this.setState({
cont: this.state.cont+1
});
}, 1000);
}
render(){
return (
<div className="App">
{ this.state.cont }
<Dom1/>
</div>
)
}
}
运行结果如下
很明显 我们的子组件dom1并没有和父组件的 cont 发生关系 但 父组件的cont每次变化 dom1 也都跟着重新渲染了
这个问题 我们只需要改一下导出的语法
有一个新特性专门解决这个问题
将
export default Dom;
改成
export default React.memo(Dom);
很明显 执行过开始的之后 就不会再触发了
这就是React.memo的作用