javascript - react : how to maintain performance when updating a large parent record from a controlled child input field?

标签 javascript reactjs

想象一个允许用户编辑账单(发票)的 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/

相关文章:

reactjs - Draft.js (react-draft-wysiwyg) : text update from the outside of the Editor component does not work

reactjs - 如何在material ui select中显示renderValue以外的值

javascript - 从 ul 获取被点击的元素

javascript - 如何在 React JS 应用程序中使用 webpack 在 img 标签中提供静态图像路径

javascript - 在多个部分中鼠标悬停

javascript - jquery - 从动态创建的元素中获取总和

javascript - 使用 React 组件登录 Firebase

javascript - slickgrid 条件格式和选择着色优先级

css - React 和 CSS 样式

reactjs - React Redux 无法从 onClick 中的方法访问 props