简体   繁体   English

React.js:在页面上插入新表单字段时如何防止浪费渲染

[英]React.js: How to prevent wasted renders when inserting a new form field on the page

I have a form with a couple of conditionally rendered fields.我有一个带有几个条件渲染字段的表单。 The form is made up of MUI components, react-hook-form and yup for its validation.该表单由 MUI 组件、react-hook-form 和用于验证的 yup 组成。

Additionally, I have added a console.log() within the AutocompleteCoffee , RadioBtnGroup , TxtField components that will execute every time the components are rendered.此外,我在AutocompleteCoffeeRadioBtnGroupTxtField组件中添加了一个console.log() ,每次渲染组件时都会执行该组件。

Scenario设想

When the page loads you can see a log from each component.当页面加载时,您可以看到每个组件的日志。 Nothing new here.这里没有什么新鲜事。

When you select "Yes" from, Do you like coffee?当您选择“是”时,您喜欢咖啡吗? a new field will be rendered.将呈现一个新字段。 This action triggers a rerender of all the components on the page.此操作会触发页面上所有组件的重新呈现。

I am using the watch method from react-hook-form to keep track of the question mentioned above.我正在使用 react-hook-form 中的watch方法来跟踪上述问题。

const coffee = watch("coffee", "No");
...
{coffee === "Yes" ? (
          <AutocompleteCoffee
            required
            fullWidth
            name="coffeType"
            label="Which coffee type"
            control={control}
            options={coffeList}
            error={!!errors.coffeType}
            helperText={errors?.coffeType?.message}
          />
        ) : null}
...

You can see the working CodeSandbox here .您可以在此处查看正在工作的 CodeSandbox

Question问题

I was wondering how to prevent all the wasted renders.我想知道如何防止所有浪费的渲染。 Any ideas?有任何想法吗?

Thank you in advance!先感谢您!

I've got this performance issue once.我曾经遇到过这个性能问题。 As per docs , you should switch to callback way of calling watch or to useWatch根据文档,您应该切换到调用watch或 useWatch 的回调方式

This API will trigger re-render at the root of your app or form, 
consider using a callback or the useWatch API
if you are experiencing performance issues.

code would look like:代码看起来像:

instead of your coffee check, do <MaybeCoffee control={control} errors={errors} /> and remove watch("coffee", "No") as well.而不是您的咖啡检查,请执行<MaybeCoffee control={control} errors={errors} />并删除 watch("coffee", "No") 。

Then add a component MaybeCoffee:然后添加一个组件 MaybeCoffee:

const MaybeCoffee = ({ control, errors }) => {
  const coffee = useWatch({ control, name: "coffee" }) || "No";
  return coffee === "Yes" ? (
    <AutocompleteCoffee
      required
      fullWidth
      name="coffeType"
      label="Which coffes type"
      control={control}
      options={coffeList}
      error={!!errors.coffeType}
      helperText={errors?.coffeType?.message}
    />
  ) : null;
}

an example https://codesandbox.io/s/testing-rerenders-forked-19invg?file=/src/components/MainForm.js一个示例https://codesandbox.io/s/testing-rerenders-forked-19invg?file=/src/components/MainForm.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM