【问题标题】:The on click handler in React.js executes before the event happens. How can I stop that?React.js 中的点击处理程序在事件发生之前执行。我怎么能阻止它?
【发布时间】:2021-01-29 03:49:16
【问题描述】:

你也可以在这里执行脚本https://codepen.io/tznqeyiq/pen/vYKNwKb

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      playStyle: '',
      playerOne: '',
      playerTwo: '',
      turn: 'one',
    };
    this.moveToNextPage = this.moveToNextPage.bind(this);
    this.onClickEventsForFirstPage = this.onClickEventsForFirstPage.bind(this);
    this.onClickEventsForSecondPage = this.onClickEventsForSecondPage.bind(this);
  }
  //// It all starts from here !!!!!!!!!!!!!!!!!!!1
  componentDidMount() {
    document.getElementById('start').style.display = 'flex';
    document.querySelector('#mainXOROdiv').style.display = 'none';
    document.querySelector('#playAreaMain').style.display = 'none';
    this.onClickEventsForFirstPage();
    this.onClickEventsForSecondPage();
  }
  /// componentDidMount is above !!!!!!!!!!!!!!!!!!!!
  /* event handlers for first page */
  onClickEventsForFirstPage() {
    var single = document.getElementById('single');
    single.addEventListener('click', () => {
      this.moveToNextPage(document.querySelector('#mainXOROdiv'));
      this.setState({
        playStyle: 'single'
      });
    });
    var double = document.getElementById('double');
    double.addEventListener('click', () => {
      this.moveToNextPage(document.querySelector('#mainXOROdiv'));
      this.setState({
        playStyle: 'double'
      });
    });
  }
  moveToNextPage(page) {
    document.getElementById('start').style.display = 'none';
    document.querySelector('#mainXOROdiv').style.display = 'none';
    document.querySelector('#playAreaMain').style.display = 'none';
    page.style.display = 'flex';
  }
  /* event handler for first page above
  event handler for second page below */
  onClickEventsForSecondPage() {
    var X = document.querySelector('#xInSpan');
    var O = document.querySelector('#oInSpan');
    var clickedBtn = '';
    X.addEventListener('click', () => {
      this.moveToNextPage(document.querySelector('#playAreaMain'));
      this.setState({
        playerOne: 'X',
        playerTwo: 'O'
      })
    });
    O.addEventListener('click', () => {
      this.moveToNextPage(document.querySelector('#playAreaMain'));
      this.setState({
        playerOne: 'O',
        playerTwo: 'X'
      })
    });
  }
  /*event handler for second page above */
  onClickEventsForBoxes = (e) => {
    if (e) {
      var a = event.target;
      console.log(this.state.playerOne, this.state.playerTwo);
      console.log(this.state.turn);
      if (this.state.turn = 'one') {
        this.setState({
          turn: 'two'
        });
        a.innerText = this.state.playerOne;
      } else {
        this.setState({
          turn: 'one'
        });
        a.innerText = this.state.playerTwo;
      }
    }
  }
  render() {
    return ( <
      div id = "component" >
      <
      div id = "start"
      class = "centredivs" >
      <
      div class = "middledivs" >
      <
      h2 > Choose game type < /h2> <
      hr id = "horirow" / >
      <
      div class = 'deepestdivs' >
      <
      h3 id = "single"
      class = "firstheadings" > SINGLE < /h3> <
      h3 id = "double"
      class = "firstheadings" > DOUBLE < /h3> <
      /div> <
      /div> <
      /div> <
      div id = "mainXOROdiv"
      class = "centredivs" >
      <
      div class = "middledivs" >
      <
      h2 > Would you like to be an X or O < /h2> <
      div class = "deepestdivs" >
      <
      span class = "xoro"
      id = "xInSpan" > X < /span><span id="oInSpan" class="xoro">O</span >
      <
      /div> <
      /div> <
      /div> <
      div id = "playAreaMain"
      class = "centredivs" >
      <
      div id = 'innerplayarea' > {
        [1, 2, 3, 4, 5, 6, 7, 8, 9].map(data => ( <
          button id = {
            data
          }
          onClick = {
            this.onClickEventsForBoxes
          }
          class = "boxes" > < /button>
        ))
      } <
      /div> <
      /div>   <
      /div>
    );
  }
}
ReactDOM.render( < App / > , document.getElementById('app'));
* {
  margin: 0;
  padding: 0;
  font-family: Arial, Helvetica, sans-serif;
}

#component {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 60vh;
  width: 60vh;
  height: 60vh;
  background: rgba(150, 160, 120, 0.3);
  border-radius: 10%;
  box-shadow: 0 0px 5px 0.01px black;
}

.centredivs {
  max-width: 80%;
  width: 80%;
  height: 80%;
  background: rgba(150, 100, 125, 0.2);
  border-radius: 10%;
  box-shadow: inset 0 0 10px rgba(225, 225, 255, 0.7);
  display: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.middledivs {
  max-height: 50%;
  height: 50%;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-around;
}

.deepestdivs {
  display: flex;
  justify-content: space-around;
  width: 80%;
  max-width: 80%;
}


/* first div css*/

#start {
  border: 0.5px solid rgba(0, 0, 0, 0.5);
  display: flex;
}

.firstheadings {
  background: rgba(0, 0, 0, 0.05);
  color: rgb(225, 225, 225);
  width: 155px;
  cursor: pointer;
  text-align: center;
  text-justify: center;
}

.firstheadings:hover {
  box-shadow: 0px 0px 5px black;
}


/* above: first div css */


/* second div css */

#mainXOROdiv {
  border: 0.8px solid rgba(0, 0, 0, 0.7);
}

.xoro {
  font-family: "Comic Sans MS", cursive, sans-serif;
  font-size: 60px;
  color: rgba(100, 100, 100, 0.7);
  cursor: pointer;
}

.xoro:hover {
  font-size: 66px;
  color: rgba(100, 100, 100, 0.9)
}


/* above: 2nd div css */


/* third div css */

#playAreaMain {
  border: 1px solid black;
}

#innerplayarea {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

.boxes:nth-child(1) {
  border-top-left-radius: 20%;
}

.boxes:nth-child(3) {
  border-top-right-radius: 20%;
}

.boxes:nth-child(7) {
  border-bottom-left-radius: 20%;
}

.boxes:nth-child(9) {
  border-bottom-right-radius: 20%;
}

.boxes {
  box-shadow: inset 0px 0px 5px rgba(225, 225, 225, 0.3);
  margin: 0;
  width: 33.2%;
  height: 32.8%;
  font-size: 500%;
  color: rgba(0, 0, 0, 0.5);
  cursor: pointer;
  font-family: "Comic Sans MS", cursive, sans-serif;
  display: flex;
  align-items: center;
  justify-content: center;
}


/* above: 3rd div css */

#app {
  width: 100vw;
  height: 100vh;
  background: rgba(100, 100, 100, 0.2);
  display: flex;
  align-items: center;
  justify-content: center;
}

#horirow {
  width: 100%;
}

@media on screen (min-width: 400px) {
  #component {
    display: block;
    overflow: scroll;
  }
}
https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js
https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js
<div id="app" class="container">

</div>

其实是用codepen.io写的。

问题出在点击事件监听器的按钮上。

                <button id={data} onClick={this.onClickEventsForBoxes} class="boxes"></button>

我想在 我真正让事件发生之后执行此操作。

它是做什么的,它首先执行然后当我再次单击按钮时它不执行。它使用先前执行的草稿。

所以基本上我每次点击按钮时都会尝试将 this.state.turn 值更改为玩家 1 和玩家 2。

 onClickEventsForBoxes=(e)=>{
    if(e){
      var a = event.target;
      console.log(this.state.playerOne,this.state.playerTwo);
      console.log(this.state.turn);
      if(this.state.turn = 'one'){
        this.setState({turn:'two'});
        a.innerText = this.state.playerOne;
      } else {
        this.setState({turn:'one'});
        a.innerText = this.state.playerTwo;
      }
    }
  }

但只有第一个 if 块正在执行,因为每个按钮的事件处理程序都是相同的。因此,状态中的值正在更改,但并未反映在代码中。

这是完整的代码。

感谢您的帮助

class App extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      playStyle: '',
      playerOne:'',
      playerTwo:'',
      turn: 'one',
    };
    this.moveToNextPage = this.moveToNextPage.bind(this);
    this.onClickEventsForFirstPage = this.onClickEventsForFirstPage.bind(this);
    this.onClickEventsForSecondPage = this.onClickEventsForSecondPage.bind(this);
  }
  //// It all starts from here !!!!!!!!!!!!!!!!!!!1
  componentDidMount(){
    document.getElementById('start').style.display= 'flex';
    document.querySelector('#mainXOROdiv').style.display = 'none';
    document.querySelector('#playAreaMain').style.display = 'none';
    this.onClickEventsForFirstPage();
    this.onClickEventsForSecondPage();
    this.onClickEventsForBoxes();
  }
  /// componentDidMount is above !!!!!!!!!!!!!!!!!!!!
  /* event handlers for first page */
  onClickEventsForFirstPage(){
    var single = document.getElementById('single');
    single.addEventListener('click',()=>{
        this.moveToNextPage(document.querySelector('#mainXOROdiv'));
        this.setState({playStyle: 'single'});
    });
    var double = document.getElementById('double');
    double.addEventListener('click',()=>{
        this.moveToNextPage(document.querySelector('#mainXOROdiv'));
        this.setState({ playStyle: 'double'});
    });
  }
  moveToNextPage(page){
    document.getElementById('start').style.display= 'none';
    document.querySelector('#mainXOROdiv').style.display = 'none';
    document.querySelector('#playAreaMain').style.display = 'none';
    page.style.display = 'flex';
  }
  /* event handler for first page above
  event handler for second page below */
  onClickEventsForSecondPage(){
    var X = document.querySelector('#xInSpan');
    var O = document.querySelector('#oInSpan');
    var clickedBtn = '';
    X.addEventListener('click',()=>{
          this.moveToNextPage(document.querySelector('#playAreaMain'));
          this.setState({playerOne:'X',playerTwo:'O'})
    });
    O.addEventListener('click',()=>{
          this.moveToNextPage(document.querySelector('#playAreaMain'));
          this.setState({playerOne:'O',playerTwo:'X'})
    });
  }
  /*event handler for second page above */
  onClickEventsForBoxes=(e)=>{
    if(e){
      var a = event.target;
      console.log(this.state.playerOne,this.state.playerTwo);
      console.log(this.state.turn);
      if(this.state.turn = 'one'){
        this.setState({turn:'two'});
        a.innerText = this.state.playerOne;
      } else {
        this.setState({turn:'one'});
        a.innerText = this.state.playerTwo;
      }
    }
  }
  render(){
    return(
     <div id="component">
        <div id="start" class="centredivs">
          <div class="middledivs">
            <h2>Choose game type</h2>
            <hr id="horirow"/>
            <div class='deepestdivs'>
              <h3 id="single" class="firstheadings">SINGLE</h3>
              <h3 id="double" class="firstheadings">DOUBLE</h3>
            </div>
          </div>
        </div>
        <div id="mainXOROdiv" class="centredivs">
          <div class="middledivs"> 
            <h2> Would you like to be an X or O</h2>
            <div class="deepestdivs">
            <span class="xoro" id="xInSpan">X</span><span id="oInSpan" class="xoro">O</span>
            </div>
          </div>
        </div>
        <div id="playAreaMain" class="centredivs">
          <div id='innerplayarea'> 
            {
              [1,2,3,4,5,6,7,8,9].map(data=>(
                <button id={data} onClick={this.onClickEventsForBoxes} class="boxes"></button>
              ))
            }
          </div>
        </div>  
     </div>
    );
  }
}  
ReactDOM.render(<App/>,document.getElementById('app'));

【问题讨论】:

  • 请用minimal reproducible example 来更新您的问题,证明问题,最好是使用堆栈片段([&lt;&gt;] 工具栏按钮)可运行。 Stack Snippets 支持 React,包括 JSX; here's how to do one.
  • 问题出在componentDidMount,你清楚地调用了函数:this.onClickEventsForBoxes();。你为什么这样做?
  • var a = event.target; to var a = e.target;
  • 每个程序员在调试时都会遇到的一个问题:D。我使用该功能来调试我的问题。但即使问题仍然存在。

标签: javascript html reactjs dom frontend


【解决方案1】:

问题可能是以下问题:

      if(this.state.turn = 'one'){

请尝试添加第二个 = 来修复它

onClickEventsForBoxes=(e)=>{
        if(e){
          var a = event.target;
          console.log(this.state.playerOne,this.state.playerTwo);
          console.log(this.state.turn);
          if(this.state.turn == 'one'){
            this.setState({turn:'two'});
            a.innerText = this.state.playerOne;
          } else {
            this.setState({turn:'one'});
            a.innerText = this.state.playerTwo;
          }
        }
      }

【讨论】:

  • 这行得通。我现在觉得很傻。 ?非常感谢楼主。你几乎让我免于整晚思考。
  • eheheheh 我们所有的程序员都有这样的问题
  • ? 我如何关闭这个帖子?还是自动关闭?我是新来这里发帖的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多