【问题标题】:Stop input from re-rendering onChange停止输入重新渲染 onChange
【发布时间】:2019-04-18 16:30:52
【问题描述】:

我将输入值捕获为状态,并在按钮提交时将结果添加到数组中。

我遇到的问题是每次我在输入字段中输入一个字符时,它都会在我点击提交按钮之前创建一个新数组。

以下是奇怪行为的截图。

这是我的代码:

import React, { Component } from "react";
import autoBind from "react-autobind";

let fixtures = [];

const submitFixture = (homeTeam, awayTeam) => {
  fixtures.push({
    homeTeam: homeTeam,
    awayTeam: awayTeam
  });
};
class CreateFixture extends Component {
  constructor(props) {
    super(props);
    autoBind(this);

    this.state = {
      homeTeam: "",
      awayTeam: ""
    };
  }

  render() {
    const { homeTeam, awayTeam } = this.state;

return (
  <React.Fragment>
    <p>Home Team</p>
    <input
      value={homeTeam}
      onChange={e => {
        this.setState({ homeTeam: e.target.value });
      }}
    />
    <p>Away Team</p>
    <input
      value={awayTeam}
      onChange={e => {
        this.setState({ awayTeam: e.target.value });
      }}
    />
    <button onClick={submitFixture(homeTeam, awayTeam)}>
      Create fixture
    </button>
    {console.log(fixtures)}
  </React.Fragment>
);
  }
}

export default CreateFixture;

【问题讨论】:

    标签: javascript reactjs forms


    【解决方案1】:

    您正在通过编写onClick={submitFixture(homeTeam, awayTeam)} 直接在渲染上调用submitFixture 函数。这样,每次重新渲染组件时,您都会向数组添加一个新元素。

    您可以创建一个新的内联函数,改为在点击事件发生时调用 submitFixture

    <button onClick={() => submitFixture(homeTeam, awayTeam)}>
    

    如果你想以某种方式渲染fixtures,最好将它们置于组件状态。

    示例

    class CreateFixture extends React.Component {
      state = {
        homeTeam: "",
        awayTeam: "",
        fixtures: []
      };
    
      submitFixture = () => {
        this.setState(({ homeTeam, awayTeam, fixtures }) => ({
          fixtures: [...fixtures, { homeTeam, awayTeam }]
        }));
      };
    
      render() {
        const { homeTeam, awayTeam, fixtures } = this.state;
    
        return (
          <div>
            <p>Home Team</p>
            <input
              value={homeTeam}
              onChange={e => {
                this.setState({ homeTeam: e.target.value });
              }}
            />
            <p>Away Team</p>
            <input
              value={awayTeam}
              onChange={e => {
                this.setState({ awayTeam: e.target.value });
              }}
            />
            <button onClick={this.submitFixture}>Create fixture</button>
            <div>{JSON.stringify(fixtures)}</div>
          </div>
        );
      }
    }
    
    ReactDOM.render(<CreateFixture />, document.getElementById("root"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="root"></div>

    【讨论】:

    • 谢谢 Tholle,这正是我所需要的。虽然每次我输入一个字符时它都会重新渲染。
    • @UmerMo 不客气!是的,当您在其中一个输入中写入一个字符时,会调用 setState,这会使整个组件重新渲染。
    【解决方案2】:

    你应该熟悉 react 生命周期:

    https://reactjs.org/docs/state-and-lifecycle.html

    setState() 总是会导致重新渲染,除非 shouldComponentUpdate() 返回 false

    https://reactjs.org/docs/react-component.html#setstate

    【讨论】:

    • 谢谢.. 感激不尽。
    猜你喜欢
    • 1970-01-01
    • 2021-01-31
    • 2021-05-19
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 2018-07-20
    • 2011-01-20
    • 2013-05-18
    相关资源
    最近更新 更多