ReactJS如何在循环中记忆以呈现相同的组件
我有一个使用循环创建多个组件的组件,但我只需要重新渲染正在修改的实例,而不需要重新渲染其余的实例。这是我的方法:ReactJS如何在循环中记忆以呈现相同的组件,reactjs,react-hooks,memoization,Reactjs,React Hooks,Memoization,我有一个使用循环创建多个组件的组件,但我只需要重新渲染正在修改的实例,而不需要重新渲染其余的实例。这是我的方法: function renderName(item) { return ( <TextField value={item.value || ''} onChange={edit(item.id)} /> ); } function renderAllNames(items) {
function renderName(item) {
return (
<TextField value={item.value || ''} onChange={edit(item.id)} />
);
}
function renderAllNames(items) {
const renderedItems = [];
items.forEach(x => {
const item = React.useMemo(() => renderName(x), [x]);
renderedItems.push(item);
});
return renderedItems;
};
return (
<>
{'Items'}
{renderAllNames(names)};
</>
);
也不管用。。。基本方法很有效
function renderAllNames(items) {
const renderedItems = [];
items.forEach(x => {
renderedItems.push(renderName(x));
});
return renderedItems;
};
但是每次我编辑任何字段时,它都会呈现所有的动态组件,那么我如何才能将其记录下来,以便只重新呈现正在编辑的项目呢?您正在破坏该选项。钩子只能在组件的顶层使用,这样React才能保证调用顺序。组件备忘录实际上也只能使用React.memo来完成,组件只能在全局范围内声明,而不能在其他组件内声明
我们可以将renderName
转换为它自己的组件,renderName
:
function RenderName({item, edit}) {
return (
<TextField value={item.value || ''} onChange={() => edit(item.id)} />
);
}
React.memo
默认情况下对所有道具进行严格比较。由于项
是一个对象,并且没有两个对象严格相等,因此必须对属性进行深入比较。旁注:只有当edit
是一个引用稳定的函数时,这才起作用。您尚未显示它,但它必须包装在自己的记忆挂钩中,例如useCallback
,或者完全脱离渲染周期
现在回到父组件中,您可以直接映射名称
:
return (
<>
{'Items'}
{names.map(name => <MemoRenderName item={name} edit={edit}/>)}
</>
);
返回(
{'Items'}
{names.map(name=>)}
);
您能提供组件的完整代码吗?嘿,我想在这里添加注释,请原谅:)编辑道具是匿名函数,可能无法通过您的平等性检查。所以,您应该使用useCallback记住这一点,或者通过命名thje函数或将其设置为变量来说明这一点。在备忘录的自定义相等函数中,可以从Lodash传递一个简单的等相等函数。也可以提高可读性,在我的op.@CaioKoiti中,我的回答假设edit
是OPs post中的命名函数。没有理由认为它是匿名的,我在回答中确实说过关于useCallback
。我不同意在这里使用深度平等检查器。在试图提高性能时,应该小心使用更昂贵的算法。更好的办法是将对象中的所有值分解为它们自己的道具,这样就根本不需要自定义检查。我在这里没有这样做,因为这篇文章的目的是阐明response.memo
是如何工作的。
const MemoRenderName = React.memo(RenderName, (prev, next) => {
const idEqual = prev.item.id === next.item.id;
const valEqual = prev.item.value === next.item.value;
const editEqual = prev.edit === next.edit;
return idEqual && valEqual && editEqual;
});
return (
<>
{'Items'}
{names.map(name => <MemoRenderName item={name} edit={edit}/>)}
</>
);