reactjs - 避免重新渲染未更改的项目
问题描述
我正在尝试使用 来提高具有可变项目的长列表的性能React.memo
,但我遇到了奇怪的行为。
重现步骤:
1 - 转到此处的沙箱
2 - 在第一个项目上按添加
3 - 在第二个项目上按添加
import React, { useState } from "react";
const App = () => {
const [list, setList] = useState([
{ id: 1, qtd: 0 },
{ id: 2, qtd: 0 },
{ id: 3, qtd: 0 },
{ id: 4, qtd: 0 }
]);
const onAdd = (id, qtd) => {
setList(
list.map((item) => {
if (item.id === id) {
return { ...item, qtd };
} else {
return item;
}
})
);
};
return (
<ul>
{list.map((item) => (
<Item {...item} onChange={onAdd} />
))}
</ul>
);
};
const Item = React.memo(({ id, qtd, onChange }) => {
console.log("Rendering -> " + id);
return (
<li>
<span>{qtd}</span>
<button onClick={() => onChange(id, qtd + 1)}>Add</button>
</li>
);
}, areEqual);
function areEqual(prev, next) {
return prev.qtd === next.qtd;
}
export default App;
解决方案
我已经修改了您的添加功能。并将 key 属性添加到 item 或 li 元素,因为这有助于反应确定 DOM 中哪个元素发生了变化。
const onAdd = (id, qtd) => {
const oldList = [...list];
oldList.forEach((element) => {
if (element.id === id) {
element.qtd=qtd;
}
});
setList(oldList);
};
<ul>
{list.map((item) => (
<Item key={item.id} {...item} onChange={onAdd} />
))}
</ul>
推荐阅读
- angular5 - 如何捕获从 UI 组件中的效果触发的 ngrx 操作?
- java - 如何重置 GUI 和游戏?
- sql - 从重复行中选择一项
- .net - 如何在 Wine 64 位前缀中安装 .NET 4?
- node.js - 如何从 Node.js 中的 SchemaTypes.Double mongoDB 中提取值
- ms-access-2013 - 如何创建 CurrentProject.connection
- java - 我自己的 Java 包作为 GitHub 上的 Maven 项目
- html - /cgi-bin .htaccess 或 apache2.config 规则会弹出密码对话框,但 cgi 在授权之前执行
- android - 如何从 zipalign (Android) 中获取错误
- javascript - 为输入文本示例 00.00 为睫毛膏创建管道