ReactJS当我使用任何handleClick时,都会触发其他handleClicks

时间:2018-08-27 17:03:12

标签: javascript reactjs

我正在尝试建立一个猜谜游戏。 我写了一个按钮来猜测一个数字,一个按钮来生成一个随机数,以及一个按钮来比较猜测的数字与生成的数字。 当我单击猜测数字按钮时,将触发handleClickCompare方法,并在其中获取console.log。并且每次触发handleChange时也会触发handleClickCompare。有时但不是每次我按猜测按钮时,都会生成一个新的随机数。 发生了什么事?

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor(props){
    super(props);
    this.state={ guess:0, gen:0 }
  }

  handleChange(guess, e) {
    this.setState({guess: e.target.value});
    console.log(this.state);
  }
  // handleChange(guess, event) {
  //   this.setState([guess]: event.target.value);
  //   console.log(this.state);
  // }
  handleClick(guess, e) {
    this.setState({ guess: e.target.value });
    console.log(this.state);
  }
  handleClickGen(gen,e){
    this.setState({gen: Math.floor(Math.random()*10)});
    console.log(this.state);
  }
  handleClickCompare(guess, gen) {
    if (gen<guess) {
    console.log("guess lower");
    }
    if (guess < gen) {
      console.log("guess higher");
    }else {
      console.log("You got it chief");
    }
  }
  


  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to React</h1>
        </header>
        <p className="App-intro">
        Enter a number
        </p>
        <input
          value={this.state.guess}
          onChange={this.handleChange.bind(this, "guess")}
          type="number"
        />
        {/* <input name={guess} onChange={event => this.handleChange(event)} /> */}
        {/* <input type="text" name="guess" value={this.state.title}
                     onChange={this.handleChange.bind(this)}/> */}
        <button type="button"
          onClick={this.handleClick.bind(this, "guess")}>
          guess{" "}
        </button>

        <button type="button"
          onClick={this.handleClickGen.bind(this, "gen")}>
          gen a number{" "}
        </button>

        <button type="button"
          onClick={this.handleClickCompare(this.state.guess, this.state.gen)}>
          compare{" "}
        </button>



      </div>
    );
  }
}

export default App;

>

3 个答案:

答案 0 :(得分:0)

您编写onClick处理程序的方式将在每次呈现组件时运行,而不仅是onClick。

例如,您应编写如下内容:

onClick={() => this.handleClick.bind(this, "guess")}>

已根据您的正确评论进行了更新:最后一个处理程序中缺少绑定。

答案 1 :(得分:0)

我认为您在这里忘记了绑定

 <button type="button"
      onClick={this.handleClickCompare.bind(this.state.guess, this.state.gen)}>
      compare{" "}
    </button>

请找到代码框-https://codesandbox.io/s/m4z2y9jmr8

答案 2 :(得分:0)

您的代码中存在一些问题和一些不良做法。让我们从回调函数开始。

this.handleChange.bind(this, "guess")

您不需要像这样绑定功能。这是不必要的,因为即使您通过引用使用它,也可以获取event参数。另外,您可以在类构造函数中绑定函数以使用this。如果您像这样绑定函数,则会在每个渲染器中重新创建它们。

this.handleClickCompare(this.state.guess, this.state.gen)

对此,有两个问题。第一个是,您不需要为此函数提供参数。您可以在函数定义中从状态中获取这些参数。没有必要。第二个问题是您要立即调用此函数,而不是将其与回调一起使用。您可以将其与箭头功能一起使用:

() => this.handleClickCompare()

但是,这又是不必要的。您可以通过引用使用它,并从状态中获取参数。

另一个问题是您的handleChange函数。

handleChange(guess, e) {
    this.setState({guess: e.target.value});
    console.log(this.state);
}

从您的输入中,您将得到一个字符串并将其设置为状态,而不是与数字进行比较。因此,使用Number()设置一个数字。

this.setState({ guess: Number(e.target.value) });

您的handleClickGen函数实际上每次生成一个数字,但您认为有时不是。

this.setState({gen: Math.floor(Math.random()*10)});

这是因为有时您看到0对吗?原因是您的函数生成的数字介于0到9之间。因此,当您的数字类似于0,...时,您的函数会将其设置为0。因此,应进行更改。

this.setState({ gen: Math.floor(Math.random() * 9) + 1 });

您的handleClickCompare逻辑有点错误,请像这样更改它:

handleClickCompare() {
  const { guess, gen }  = this.state;
  console.log( guess, gen );
  if (guess < gen) {
    console.log("guess lower");
  } else if (guess > gen) {
    console.log("guess higher");
  } else {
    console.log("You got it chief");
  }
}

最后,不要立即在函数中更新状态后记录状态。 setState是异步的。您可以像下面一样将其记录在渲染方法中。

顺便说一句,由于您的handleChange函数已经设置了guess状态,因此我将“ guess”选项更改为“ reset”。

所以,这是完整的代码:

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { guess: 0, gen: 0 };
    this.handleChange = this.handleChange.bind(this);
    this.handleClickGen = this.handleClickGen.bind(this);
    this.handleClick = this.handleClick.bind(this);
    this.handleClickCompare = this.handleClickCompare.bind(this);
  }

  handleChange(e) {
    this.setState({ guess: Number(e.target.value) });
  }

  handleClick() {
    this.setState({ guess: 0 });
  }

  handleClickGen() {
    this.setState({ gen: Math.floor(Math.random() * 9) + 1 });
  }

  handleClickCompare() {
    const { guess, gen }  = this.state;
    console.log( guess, gen );
    if (guess < gen) {
      console.log("guess lower");
    } else if (guess > gen) {
      console.log("guess higher");
    } else {
      console.log("You got it chief");
    }
  }

  render() {
    console.log( this.state );
    return (
      <div className="App">
        <p className="App-intro">
          Enter a number
        </p>
        <input
          value={this.state.guess}
          onChange={this.handleChange}
          type="number"
        />
        <button type="button"
          onClick={this.handleClick}>
          Reset{" "}
        </button>

        <button type="button"
          onClick={this.handleClickGen}>
          gen a number{" "}
        </button>

        <button type="button"
          onClick={this.handleClickCompare}>
          compare{" "}
        </button>
      </div>
    );
  }
}

ReactDOM.render(<App />, 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>