React.memo函数中的参数示例详解
目录
- React.memo?这是个啥?
- React.memo的第一个参数
- 父组件
- 子组件
- React.memo优化
- React.memo的第二个参数
- 父组件
- 子组件
- React.memo优化
- 父组件
- 子组件
- 小结
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函数参数的资料请关注我们其它相关文章!