[英]How to maximize performance in React when taking controlled input from multiple components?
[英]React: how to maintain performance when updating a large parent record from a controlled child input field?
想象一個允許用戶編輯賬單(發票)的 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
作為道具接收。 考慮使用useCallback
來useCallback
updateBill
函數:
const updateBill = useCallback(updatedLineItem => {
setBill(bill => {
const newLineItems = [...bill.lineItems];
newLineItems[updatedLineItem.index] = updatedLineItem;
return {
...bill,
lineItems: newLineItems
}
})
}, []);
感謝大家的想法和建議。 你幫我理清了思路,我找到了問題所在。 bill
會在每次按鍵時更新,它依賴於useEffect
鈎子,事實證明,它非常昂貴並導致大量重新渲染。 我重構了useEffect
並且我的按鍵性能現在非常可接受,即使在開發模式下也是如此。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.