【问题标题】:Best way to pass huge object from children to parent?将巨大物体从孩子传递给父母的最佳方式?
【发布时间】:2020-09-07 20:03:24
【问题描述】:

我有一个巨大的表单,并且从表单外部触发了 sumbit

<App>
   <Form/>
   <Button/>   
</App>

问题是我需要在按钮组件中有当前表单字段对象。我尝试通过传递 setState 函数来通过多个层传递状态:

const [formFields, setFormFields] = useState(null);    
<App>
   <Form setData={setFormFields}/>
   <Button data={formFields}/>   
</App>

并且还可以在按钮组件中使用 redux 调度(在表单字段更改时)和 useSelector 来获取当前数据。但是当我在输入字段中写一些文本时,这两种方法似乎真的减慢了应用程序的速度。

优化它的最佳解决方案是什么?

【问题讨论】:

  • 为什么你的按钮组件需要整个 formFields 状态?
  • 我需要所有的表单数据都来自按钮组件触发的 POST 请求
  • 我明白了。将submit 回调(和其他一些小事)传递给Button 怎么样,以便包含formfields 状态的组件执行发布请求?

标签: reactjs


【解决方案1】:

当我在输入字段中写一些文本时,应用程序的速度真的很慢。

这是因为您将表单的数据 绑定到呈现。只要您没有在组件的渲染生命周期和表单字段值中的那些突变之间创建依赖关系,也可以通过 Redux 存储整个表单(或任何其他地方)。

整个表单是否需要根据每个单独组件的事件进行更新?并不真地。但是,由于整个表单都集中在一个大对象中,并且该对象的引用在更新后发生了更改,因此整个组件树都会重新渲染。

为了减少重新渲染的需要,您可以在 React 之外同步数据(注意:数据,而不是验证等),并且仅在您提交时获取它.

import React, { useState } from "react";

const externalFormData = {};

function Form() {
  return (
    <input
      onChange={function(ev) {
        externalFormData.input = ev.target.value;
      }}
    />
  );
}

export default function App() {
  const [formData, setFormData] = useState();
  return (
    <div>
      <Form />
      <input
        type={"button"}
        onClick={function() {
          setFormData(externalFormData);
        }}
        value="Submit form"
      />
      <p>{`Submitted form is: ${JSON.stringify(formData)}`}</p>
    </div>
  );
}

如果这是您的选择,我建议您寻找一些现有的表单库来为您处理(包括验证等)。

另一个想法是将您提到的这个“大对象”解耦成单独更新的单独对象,因此只会触发受值影响的组件的重新渲染。

【讨论】:

  • 我会试试你的建议。我知道这个问题与重新渲染有关。如果我使用 onBlur 而不是 onChange 会怎样?这会导致任何其他问题吗?
  • 我能想到两件事:1. 一旦用户开始单独使用onBlur 输入,您将无法清除错误字段。 2、用户在点击提交按钮之前,不知道当前字段是否有错误,因为onBlur只有在点击按钮时才会触发。就获取值而言,我认为不会有问题。
猜你喜欢
  • 2020-07-22
  • 1970-01-01
  • 2018-06-29
  • 1970-01-01
  • 2021-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
相关资源
最近更新 更多