避免不必要的组件更新。
将 props 设置为数组或对象
每次调用 React 组件都会创建新组件,就算传入的数组或对象的值没有改变,他们的引用地址也会发生改变,比如,如果按照如下的写法,那么每次渲染时 style 都是一个新对象
// 不推荐
<button style= />
// 推荐
const style = { color: 'red' }
<button style={style} />
// 不推荐
<button style={this.props.style || {} } />
// 推荐
const defaultStyle = {}
<button style={this.props.style || defaultStyle } />
使用 PureComponent、React.memo、useCallback、useMemo、useContext 跳过不必要的组件更新。
通常当父组件更新时,子组件也会跟着更新,即使 props 没有变更。
使用 memo
包裹子组件,这样当父组件更新时,子组件的 props 没有更新,子组件便不会更新。当然只有当 props 为基础数据类型时才生效。如果传递参数为对象或者函数,依然有问题。
可以使用 useCallback
包裹函数,useMemo
包裹对象之后再传递给子组件。
import { useMemo, useState, useCallback } from "react";
import { Child } from "./child";
export const Parent = () => {
const [count, setCount] = useState(0);
const [name, setName] = useState('小明');
// const [userInfo, setUserInfo] = useState({ name: "小明", age: 18 });
const increment = () => setCount(count + 1);
const userInfo = useMemo(() => ({ name, age: 18 }), [name]); // 当 name 变更时,重新执行useMemo第一个参数(函数),得到新的 userInfo
const onClick = useCallback((name: string) => {
setName(name);
}, []);
return (
<div>
<button onClick={increment}>点击次数:{count}</button>
<Child
onClick={onClick}
userInfo={userInfo}
/>
</div>
);
};
import { memo } from "react";
export const Child = memo(
(props: { userInfo: { name: string; age: number; onClick: (value: any) => void; } }) => {
const { userInfo, onClick } = props;
console.log("渲染了", userInfo);
return (
<>
<div>名字: {userInfo.name}</div>
<div>年龄:{userInfo.age}</div>
<button onClick={onClick}>按钮</button>
</>
);
}
);
列表渲染使用 key 属性
给列表项设置唯一 key,在 diff 算法中,会用 key 作为唯一标识优化渲染。
参考
https://juejin.cn/post/7039256825656524807
https://juejin.cn/post/6935584878071119885