前言:
如果父组件的state发生变化,那么就需要重新render。其下的子组件即使没有用到此state,也会跟着重新render。性能受影响。
现有方法 react.memo 能实现,只有当子组件的 props里的数据发生变化后,才会重新render。
注: react.memo 此方法是浅比较。
父组件
父组件的input框输入的时候,会引起 inp_value 的变化。必然引起父组件的重新render。但是此时并没有引起子组件的render
案例中,我使用了usecallback,第二个参数传递空数组,生成了一个不会随着任何state变化而变化的函数 fa_callback ,此函数传递给子组件。
同理test_value一个当父组件更新时不会变化的普通state,传递给子组件。
export default function Reactuse() {const [inp_value, setinp_value] = useState('123');const [test_value, settest_value] = useState('456');// 这个函数没有依赖项,不会被更新。即使此组件重新渲染const fa_callback = useCallback(() => {console.log('父组件的useCallback函数 ------------ ');}, []);useEffect(() => {console.log(inp_value, 'inp_value变了');}, [inp_value]);return (<div><inputtype="text"value={inp_value}onChange={(e) => {setinp_value(e.target.value);}}/>//一个不会发生变化的函数fa_callback 和 一个未变化的 数据test_value<Test3 fa_callback={fa_callback} test_value ={test_value}/></div>);
}
子组件
import React, { useState, useEffect } from 'react';
import eventEmmiter from '../config/tools';function Test3(props) {
//下面这句执行就说明,子组件重新渲染了console.log('组件3 didupdata -----------');useEffect(() => {console.log('组件3 didmount -----------');}, []);return (<div style={
{ backgroundColor: 'pink', width: '300px', height: '200px' }}>子组件3 !!!<buttononClick={() => {props.fa_callback();}}>点击执行父组件的方法</button></div>);
}
//下面是重点!!!
export default React.memo(Test3);
如图我在输入框里输入文字,inp_value变化了,但是组件3并没有重新render
下图是没使用 memo的情况
React.memo的第二个参数!
function MyComponent(props) {
/* 使用 props 渲染 */
}
function areEqual(prevProps, nextProps) {
/*如果把 nextProps 传入 render 方法的返回结果与将 prevProps 传入 render 方法的返回结果一致则返回 true,否则返回 false*/
}
export default React.memo(MyComponent, areEqual);
总结
借用大佬的话
useCallback 是要配合子组件的 shouldComponentUpdate 或者 React.memo
一起来使用的,否则就是反向优化。
参考文献