如何减少重渲染并缓存Props?父传空对象致子组件重渲染的解决方法
避免空对象Props引发子组件不必要重渲染的方案
问题根源
你遇到的问题核心是:父组件每次渲染时,当index不存在或对应form.user[index]为空时,都会创建新的空对象({})。由于对象是引用类型,每次新建的空对象引用地址不同,React会判定user props发生了变化,进而触发子组件的不必要重渲染。
解决方案
1. 复用空对象引用
在父组件中定义一个全局的空对象常量,每次需要空对象时都复用这个引用,避免每次创建新对象:
// 定义复用的空对象常量 const EMPTY_USER = {}; const user = index !== undefined ? form?.user?.[index] ?? EMPTY_USER : EMPTY_USER; <AddOrEditUserModal user={user} />
这样无论父组件渲染多少次,空状态下的user都是同一个引用,React不会认为props有变化,子组件就不会无故重渲染。
2. 用React.memo包裹子组件
给子组件加上React.memo,让它只在props真正发生变化时才重渲染。结合上面的复用空对象方案,能最大化避免不必要渲染:
import { memo, useState } from 'react'; const AddOrEditUserModal = memo(({ user }) => { const [editedUser, setEditedUser] = useState(user); const onChange = (event) => { const { name, value } = event.target; setEditedUser({ ...editedUser, [name]: value, }); }; // 组件其他逻辑与JSX return (/* 你的模态框内容 */); }); export default AddOrEditUserModal;
React.memo默认会对props做浅比较,如果你的user是复杂对象,浅比较已经足够识别引用变化;如果需要深比较,可以给memo传第二个自定义比较函数,但一般场景下浅比较就够用。
3. 可选:同步父组件user变化到子组件状态
子组件中useState(user)只会在第一次挂载时初始化状态,如果父组件的user后续发生变化(比如切换编辑用户),子组件的editedUser不会自动同步。可以用useEffect监听user来同步:
const [editedUser, setEditedUser] = useState(user); useEffect(() => { setEditedUser(user); }, [user]); // 当user引用变化时更新状态
内容的提问来源于stack exchange,提问作者user21175044
相关产品推荐
相关产品推荐

