想象一个允许用户编辑账单(发票)的 React 页面。该帐单具有相当数量的可编辑字段,例如 100 个。此外,帐单可以包含任意数量的行项目。让我们想象一下其中的 100 个,每个都有 20 个字段。
如果账单是“父级”,并且由 React 组件呈现,则行项目是“子级”,每个项目都由“子”组件呈现。
我正在父组件中维护帐单(及其行项目)的状态,这感觉不错。
我想在子(行项目)组件中使用受控输入字段。然而,这至少天真地意味着,即使我明智地使用 React.memo,每次按键都会导致父(账单)组件中的状态更新,以及一些重新渲染。
即使只有 10 个行项目,性能也很快变得令人无法接受,例如每次按键有 500-800 毫秒的延迟。我已经做了相当多的性能调查,并有一些潜在的答案,但我不会在这里报告它们,以免阻碍任何获得最佳答案的途径。
必须有一个通用的解决方案,不是吗?我想在没有表单库的情况下完成此操作,尽管我并不完全反对这一点。
下面的精简示例只是为了演示基本架构。 该示例没有性能问题。:-)
救命啊!为了保持这种性能,我缺少什么魔力?
const INITIAL_STATE = {
invoiceNumber: "ABC123",
customer: "Phil's Dills",
lineItems: [
{ index: 0, item: "Pickles", quantity: 2 },
{ index: 1, item: "Pickle Juice", quantity: 5 },
]
}
export function Bill() {
const [ bill, setBill ] = useState(INITIAL_STATE);
function updateBill(updatedLineItem) {
const newLineItems = [...bill.lineItems];
newLineItems[updatedLineItem.index] = updatedLineItem;
setBill({
...bill,
lineItems: newLineItems
})
}
return(
<div id="parent">
<h1>Bill {bill.invoiceNumber} for {bill.customer}</h1>
{bill.lineItems.map((lineItem) => (
<LineItem key={lineItem.index} line={lineItem} updateBill={updateBill} />
))}
</div>
);
}
function LineItem({ line, updateBill }) {
function updateField(e) {
updateBill({
...line,
[e.target.id]: e.target.value
});
}
return(
<div id="child">
<input id="quantity" value={line.quantity} onChange={updateField} />
<input id="item" value={line.item} onChange={updateField} />
</div>
);
}```
最佳答案
我认为您的问题实际上是,每次此组件重新渲染时您都会重新创建 updateBill
,这意味着每个子组件也会重新渲染,因为它们都会收到 updateBill
code> 作为 Prop 。考虑使用 useCallback
来内存 updateBill
函数:
const updateBill = useCallback(updatedLineItem => {
setBill(bill => {
const newLineItems = [...bill.lineItems];
newLineItems[updatedLineItem.index] = updatedLineItem;
return {
...bill,
lineItems: newLineItems
}
})
}, []);
关于javascript - react : how to maintain performance when updating a large parent record from a controlled child input field?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60272426/