停止重新渲染onChange的输入

时间:2018-11-15 14:31:18

标签: javascript reactjs forms

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

我遇到的问题是,每当我在输入字段中键入一个字符时,它就会在我甚至没有按下提交按钮的情况下创建一个新数组。

以下是怪异行为的屏幕截图。

enter image description here

这是我的代码:

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;

2 个答案:

答案 0 :(得分:3)

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

您可以创建一个新的内联函数,当点击事件发生时调用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>

答案 1 :(得分:1)

您应该熟悉反应生命周期:

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

  

setState()将始终导致重新渲染,除非shouldComponentUpdate()返回false

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