react教程,memo高阶函数的高级使用方法,有条件的更新
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
本文描述react
项目中的高阶函数memo
,前面的文章里面,苏南大叔对这个memo
已经做过简单的描述了,最基本的印象就是用于监控组件的props
的变化情况,如果props
没有变化,就不更新组件。这个组件可以是函数式组件,也可以是类式组件。
苏南大叔的程序如此灵动博客,记录苏南大叔的代码感想。本文描述react
高阶组件memo
的高级使用方式:有条件的允许更新。测试环境:create-react-app@5.0.1
,react@18.2.0
,react-dom@18.2.0
,node@16.14.2
。
前置内容
本文的前置内容是下面的这篇文章:
本文的例子,和上文的例子非常类似。但是,本文中使用类式组件【以及函数式组件】来做子组件的例子,然后使用高阶函数memo
来做这个有条件的缓存。
父组件
import './App.css';
import React, { useState, memo, Component } from 'react';
function App() {
const [selfData, setSelfData] = useState(0) // 不传入子组件
const [nextData, setNextData] = useState(1) // 传入子组件
return (
<div className="App">
<table>
<tbody>
<tr>
<td>
<button onClick={() => setSelfData((val) => val + 1)}>selfData,不应该引起子组件渲染,但是引起了</button>
</td>
<td>{selfData}</td>
</tr>
<tr>
<td>
<button onClick={() => setNextData((val) => val + 1)}>nextData,应该引起子组件渲染,5之后不渲染</button>
</td>
<td>{nextData}</td>
</tr>
</tbody>
</table>
<Child nextData={nextData} />
<Child2 nextData={nextData} />
</div>
);
}
export default App;
函数式组件memo
// import React,{memo} from 'react';
const Child_ = (props) => {
const { nextData } = props
return (
<>
{
console.log('函数组件渲染了!!!', Date.now().toString().slice(-6))
}
<table>
<tbody>
<tr>
<td>函数组件nextData</td>
<td>{nextData}</td>
</tr>
<tr>
<td>函数组件被渲染时间</td>
<td>{Date.now().toString().slice(-6)}</td>
</tr>
</tbody>
</table>
</>
)
}
const Child = memo(Child_, (prev, next) => {
console.log(prev, next);
if (prev.nextData < 5) return false; //允许更新
return true; //不允许更新
})
类式组件memo
// import React,{memo} from 'react';
class Child2_ extends Component {
constructor(props) {
super(props)
}
componentDidUpdate() {
console.log('类式组件渲染了!!!', Date.now().toString().slice(-6))
}
render() {
return (<table>
<tbody>
<tr>
<td>类式组件nextData</td>
<td>{this.props.nextData}</td>
</tr>
<tr>
<td>类式组件被渲染时间</td>
<td>{Date.now().toString().slice(-6)}</td>
</tr>
</tbody>
</table>)
}
}
const Child2 = memo(Child2_, (prev, next) => {
console.log(prev, next);
if (prev.nextData < 5) return false; //允许更新
return true; //不允许更新
})
执行效果
本文执行效果如下:
父组件中,有两个按钮,第一个按钮总是会引起子组件更新。第二个按钮在计数到5之前会引起两个子组件的更新。
第二个参数 对比 shouldComponentUpdate
memo
的第二个参数是个回调函数:
(prev, next) => {
console.log(prev, next);
//return false; //允许更新
return true; //不允许更新
}
这个看起来和shouldComponentUpdate
很类似,可以回顾一下shouldComponentUpdate
的用法:
shouldComponentUpdate(nextProps, nextState) {
console.log('shouldComponentUpdate');
console.log(nextProps, nextState);
// return false;
return true;
}
可见两者区别是:
函数 | 辨别标准 | return true | return false |
---|---|---|---|
memo(,(prev, next)=>{}) | 前后props | 不允许更新 | 允许更新 |
shouldComponentUpdate(nextProps, nextState) | 下一个props 和state | 允许更新 | 不允许更新 |
总结
memo
虽然客观上是要保持缓存组件的,但是组件的缓存条件也可以是有条件的。特别需要注意的是:这里的true
和false
表达的意思,和shouldComponentUpdate()
是相反的!!!
更多react
经验文章,请点击苏南大叔的博客:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。