React.memo?这是个啥?
按照官方文档的解释:
如果你的函数组件在给定相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo 中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。这意味着在这种情况下,React 将跳过渲染组件的操作并直接复用最近一次渲染的结果。
官方文档??(React 顶层 API – React (reactjs.org))
个人浅见:
每一次状态的更新都会导致整个组件的重复渲染,而React.memo可以避免与这次状态更新原因无关组件的重复渲染。如果还不是很懂,没关系,下面的demo肯定能让你明白
React.memo的第一个参数
就拿实际开发中常见的父子组件传值
来举例:
父组件
import { useEffect,useState } from 'react';
import SonComponent from './SonComponent';
function App() {
const [satisfactionLevel,setSatisfactionLevel] = useState(100);
console.log('App 更新了');
useEffect(() => {
setTimeout(() => {
setSatisfactionLevel(150)
},3000)
},[])
return (
<div className="App">
{satisfactionLevel}
<SonComponent />
</div>
)
}
export default App
子组件
import React from 'react'
function SonComponent() {
console.log('SonComponent 更新了');
return (
<div>
SonComponent
</div>
)
}
export default SonComponent
父组件:我自身的satisfactionLevel状态发生了变化,我得重新渲染一下
结果
子组件:我刚开始不是已经执行过了吗?而且我本来就是好好的,为啥我要因为你(父组件)的变化而重新执行??我不服!!
哦吼,情况不妙,要吵起来了。。。
??俗话说:有问题来调节,来调节没问题
这时React.memo
金牌调节官来了~~
React.memo优化
调节官:来来来,子组件呀,我把我的React.memo给你,绝对让父组件变得老老实实的。
import React from 'react'
function SonComponent() {
console.log('SonComponent 更新了');
return (
<div>
SonComponent
</div>
)
}
export default React.memo(SonComponent)
结果
可以发现在使用了React.memo后,可以使子组件避免无效的渲染,从而提高性能
React.memo的第二个参数
很多人知道了memo第一个参数的威力后,就往往把它第二个参数忽略了
上一个案例是父组件状态的更新与子组件无关,用React.memo 进行缓存渲染,故不更新子组件
那么父组件状态的更新与子组件有关,就一定要更新吗?
啊嘞啊嘞~~什么鬼?
那么我们再拿个表单的刻度滑动举例看看吧
父组件
import { useEffect,useState } from 'react';
import SonComponent from './SonComponent';
function App() {
const [satisfactionLevel,setSatisfactionLevel] = useState(100);
// console.log('App 更新了');
useEffect(() => {
setTimeout(() => {
setSatisfactionLevel(150)
},3000)
},[])
return (
<div className="App">
<input type="range"
min='0'
max='300'
value={satisfactionLevel}
onChange={(event) => setSatisfactionLevel(+event.target.value)} />
{satisfactionLevel}
<SonComponent level={satisfactionLevel}/>
</div>
)
}
export default App
子组件
import React from 'react'
function SonComponent(props) {
console.log(`${props.level}`);
return (
<div>
SonComponent
</div>
)
}
export default React.memo(SonComponent)
结果
OMG!!难道每拖动一个地方就要重新渲染吗?这不是更降低性能吗?
这就到了我们React.memo大显身手的时候了!!
React.memo优化
父组件
import { useEffect,useState } from 'react';
import SonComponent from './SonComponent';
function App() {
const [satisfactionLevel,setSatisfactionLevel] = useState(100);
// console.log('App 更新了');
useEffect(() => {
setTimeout(() => {
setSatisfactionLevel(150)
},3000)
},[])
return (
<div className="App">
<input type="range"
min='0'
max='300'
value={satisfactionLevel}
onChange={(event) => setSatisfactionLevel(+event.target.value)} />
{satisfactionLevel}
<SonComponent level={satisfactionLevel}/>
</div>
)
}
export default App
子组件
import React from 'react'
function SonComponent(props) {
console.log(`${props.level}`);
return (
<div>
SonComponent
</div>
)
}
const setSatisfactionClass = (level) => {
if (level < 100) {
return "bad";
}
if (level < 200) {
return "common";
}
if (level < 300) {
return "good";
}
}
const isSameRange = (prevValue, nextValue) => {
// 将上一个刻度与下一个刻度进行比较,如果返回值相同,则不会进行更新
// 上一个刻度的返回值
const prevValueClass = setSatisfactionClass(prevValue.level);
// 下一个刻度的返回值
const nextValueClass = setSatisfactionClass(nextValue.level);
return prevValueClass === nextValueClass
}
export default React.memo(SonComponent,isSameRange)
结果
直接把表单分成了三个区域,0-100,100-200,200-300,如果仅仅是在同一个区域里面做拖动,子组件不会进行额外的渲染
小结
**React.memo() 第一个参数是要包裹的组件**
**第二个参数为前后props的值的比较方式**
1. 默认情况下,只会对复杂对象做浅层对比,即仅仅使用React.memo的第一个参数
2. 如果想要控制对比过程,那么可以自定义比较函数,通过第二个参数传入来实现
以上就是React.memo函数中的参数示例详解的详细内容,更多关于React.memo函数参数的资料请关注编程网其它相关文章!