【问题标题】:React - How do I handle changes for large sets of dynamic inputs?React - 如何处理大量动态输入的更改?
【发布时间】:2019-01-08 14:56:09
【问题描述】:

我正在寻找一种最简洁的方法来处理表单中数百个动态创建的输入的输入更改。我遇到的问题是,当我从父组件传递一个处理程序时,该处理程序会在用户输入给定输入时更新父组件的状态对象,渲染输入中的新值变得缓慢且不稳定。

我还尝试在每个子组件的状态中使用单独的事件处理程序和“editValue”,并在用户点击提交按钮以更新其状态对象时将其发送给父级,但这似乎没有必要并且没有满足我的票证要求。

export default class Parent extends Component {
  state = {
    // Object will look like this with substantially more categories and input fields per category
    inputFieldsData: {
      personalInfo: {
        allApproved: false,
        inputs: {
          name: {
            approvalState: 'approved',
            value: 'Joe Johnson',
          },
          email: {
            approvalState: 'rejected',
            value: 'jjohnson@gmail.com', 
          },
        }
      },
      companyInfo: {
        allApproved: true,
        inputs: {
          companyName: {
            approvalState: 'approved',
            value: 'ABC Inc.'
          }
        }
      }
    },
  }

  handleTextChange = (category, field, value) => {
    this.setState((prevState) => {
      const inputFieldsData = prevState.inputFieldsData;
      inputFieldsData[category].inputs[field].value = value;
      return { inputFieldsData };
    });
  }

  render() {
    return (
      <div>
        {
          Object.keys(this.state.inputFieldsData).map((category) => {
            <InputsTable 
              category={category}
              handleTextSubmit={this.handleTextSubmit} 
              inputFieldsData={this.props.inputFieldsData} />
          })
        }
      </div>
    );
  }
}

export default class InputsTable extends Component {
  render() {
    const category = this.props.category;

    return (
      <>
        <table>
          <tbody>
            {
              Object.keys(this.props.inputFieldsData[category]).map((input) => {
                <Child 
                  category={category}
                  value={this.props.inputFieldsData[category].inputs[input].value} 
                  handleTextChange={this.props.handleTextChange} />
              })
            }
          </tbody>
        </table> 
      </>
    );
  }
}

export default class Child extends Component {
  handleChange = (e) => {
    this.props.handleTextChange(this.props.category, this.props.name, e.target.value);
  }

  render() {
    return (
      <tr>
        <input 
          type="text" 
          value={this.props.value} 
          onChange={this.handleChange} />
      </tr>
    );
  }
}

我希望父级中的 state 对象能够更新并将适当的 value prop 传递给每个输入,而不会在键入时出现任何断断续续的情况。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    这个问题不是使用类与无状态组件引起的,这是没有意义的。 React 文档从未说过使用无状态组件会带来性能提升,只是可能在未来会有。但是,纯组件可能会显着提高性能,因为它减少了应用程序中的渲染操作次数。

    https://reactjs.org/docs/react-api.html#reactpurecomponent

    就问题而言,我认为这更像是一个架构问题。您正在迭代并创建多个表,每个表都包含自己的输入,并在父级中保持状态。即使正在更新一个输入,父级也会重新渲染每个表。

    1. 一种可能的解决方案是实现 shouldComponentUpdate 每个 InputTable 中的生命周期挂钩。如果与此相关的数据 表没有改变,它不应该更新。现在你只有一个 表格重新渲染与所有这些。

      查看 shouldComponentUpdate 的文档https://reactjs.org/docs/react-component.html#shouldcomponentupdate

    2. 一个不太优雅的解决方案是将每个 InputTable 的状态保持在 低等级。在大多数情况下,这不是正确的解决方案,但 可以解决你的问题。我强烈建议研究解决方案 #1。

    React 有 this 谈论优化性能,这将是一本有趣的读物。特别是与避免和解相关的部分将对您有用。

    【讨论】:

      【解决方案2】:

      首先,您的 2 个组件内部没有任何状态逻辑(InputsTable 和 Child)。
      您可以将它们转换为我们所说的无状态组件。使用它们可以提高性能,因为它们承载的逻辑更少。
      有很多文章在谈论它们以及它的好处。

      无状态组件示例:
      const Username = function(props) { return <p>The logged in user is: {props.username}</p>; };

      但是这可能还不够。这更复杂,但还有其他“模式”可以通过 react 创建具有较少渲染操作的组件。
      那里发生的情况是您的父组件拥有所有信息,获取他的状态更新然后重绘他的所有子组件。
      这可能会很有趣:https://medium.com/@ohansemmanuel/how-to-eliminate-react-performance-issues-a16a250c0f27

      【讨论】:

      • 在安装组件而不是重新渲染时,使用类组件与功能组件不会对性能造成影响吗?你能解释一下你所说的功能组件“携带更少的逻辑”是什么意思吗?我故意使用所有类组件,因为当需要移动状态时更容易重构代码。我还没有看到通过使用功能组件显着提高内部性能的好论据,但我愿意被说服。
      猜你喜欢
      • 2021-07-27
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 2021-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-19
      相关资源
      最近更新 更多