引:一直听说有memo这个方法用来做优化特别的合适,但是开发中用到的很少,可能写的代码质量不高,不够复杂,没有出现性能问题,但对这个东西很是好奇,决定研究一下,并在以后的开发中加入进去,求个舒服
使用场景
运用官方的话
如果你的组件在相同 props 的情况下渲染相同的结果,那么你可以通过将其包装在 React.memo中调用,以此通过记忆组件渲染结果的方式来提高组件的性能表现。这意味着在这种情况下,React将跳过渲染组件的操作并直接复用最近一次渲染的结果。
总结一下就是,你的组件在props不改变的情况下渲染结果相同,可以通过memo来定义组件,注意,memo只对props进行变更检查,如果组件自身的状态或者上下文变更引起的重新渲染,memo不做检查也不会阻拦;
所以目标很明确了,就是在父子组件中,由于父组件自身重新渲染引起子组件无意义的重新渲染导致资源浪费,此时memo定义你的子组件,来避免和子组件无关的props变更引起的渲染,以此达到优化效果。
简单小试
父组件:
<>
<p>我是memo首页:{name}</p>
<input onChange={(el) => setinfo({ sex: el.target.value })} />
<p>我是memo-child页</p>
<Child name="alex" info={info} />
</>
子组件:
export default memo(({ name, info }) => {
useEffect(() => {
window.console.log('child useEffect');
}, [name]);
window.console.log('child render');
return (
<>
{name}:{info?.sex}
</>
);
});
可以尝试以下操作
1、父组件name属性变更时,父组件本身会重绘,但是子组件child的props中没有依赖父组件的状态,所以child没有重绘
2、更新父对象的info内容,此时子组件会重绘,因为对象本质的引用地址改变了,子组件也会变更,有种情况比较特殊,如下
如果父组件这样引用子组件
<Child name="alex" info={{sex:'男;} />
这个时候只要父组件重绘,子组件是一定会重绘的,因为每次info都是新的对象,这个涉及到引用类型的概念,比较基础,懂的都懂~
但有时候可能为了方便,开发的时候传递值就是会写成这样,直接在组件调用的地方写字面量对象,为了也能达到memo优化的效果,就需要memo第二个参数来详细制定子组件重绘规则,第二个参数是个函数,如下
export default memo(({ name, info }) => {
useEffect(() => {
window.console.log('child useEffect');
}, [name]);
window.console.log('child render');
return (
<>
{name}:{info?.sex}
</>
);
},
(prev, next) => prev.info.sex !== next.info.sex);
这里的函数返回一个boolean值,大家可以在这里进行值判断,返回true的话会重绘组件,如果返回false,则达到优化效果
后续有发现再做补充