如何从驻留在React组件上的函数调用函数

时间:2018-02-03 14:54:56

标签: javascript reactjs

我正在尝试使用事件处理程序调用函数 this.getCurrentMarioPosition()但是它说 getCurrentMarioPosition 不是调用它的处理程序的函数。我正在为文档的事件监听器添加处理程序。当这个实际上意味着文档不是组件时,这可能是一个问题吗?如果是,那么这个问题的解决方法或解决方案是什么?

我认为 handleKey 附加到文档对象的问题,所以当我说这个时它就是' s引用文档对象而不是组件。因为在其他函数中我以相同的方式调用它并且它正在工作。如何从handleKey方法获取Component的上下文?

我的代码:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';


class Square extends React.Component {
  constructor(props){
    super(props)
    this.state={
      showMushroom:props.showMushroom,
      showMario:props.showMario,
    }
  }
  render(){
    if(this.state.showMushroom){
      return (
        <button className="square" >
        </button>
      );
    }else if(this.state.showMario){
      return (
        <button className="square-mario" >
        </button>
      );
    }else{
      return (
        <button className="square-plain" >
        </button>
      );
    }

  }

}

class Board extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rows:[],
      cols:[],
      occupiedCells:[],
      dimX:10,
      dimY:10,
      isMarioSet:false,

    };

    for(let i=0;i<this.state.dimX;i++){
      let colarray=new Array(10);
      for(let j=0;j<this.state.dimY;j++){
        let justRandomInt=Math.floor(Math.random(1,76)*10);

        if(justRandomInt % 2 ===0){
          colarray[j]=1;
        }else{
          colarray[j]=0;
        }
      }
      this.state.occupiedCells.push(colarray);
    }

    this.fillTheBoard();

    console.log(this.state.occupiedCells);
  }

  fillTheBoard(){

    for(let i=0;i<this.state.dimX;i++){
      for(let j=0;j<this.state.dimY;j++){
        this.state.cols.push(this.renderSquare(i,j))
      }
      this.state.rows.push(this.renderRow(this.state.cols));
      this.state.cols=[];
    }


  }



  componentWillMount(){
    console.log(document);
    document.addEventListener('keydown',this.handleKey,false);
  }

  handleKey(event){
    if(event.keyCode === 37){
        this.getCurrentMarioPosition();
    }
  }

  getCurrentMarioPosition(){
    for(let i=0;i<this.state.dimX;i++){
      for(let j=0;j<this.state.dimY;j++){
        if(this.state.occupiedCells[i][j]===-1){
          console.log([i,j]);
          return [i,j];
        }
      }
    }
  }

  generateRandomForColumn(){
    return Math.floor(Math.random(1,6)*10);
  }

  renderRow(cols){
    return(
      <div className="board-row">
        {cols}
      </div>
    );
  }



  renderSquare(i,j) {
    let showMushroom=false;
    let showMario=false;
    if(this.state.occupiedCells[i][j]===1)
      showMushroom=true;
    else{
      if(!this.state.isMarioSet){
        this.state.occupiedCells[i][j]=-1;
        this.state.isMarioSet=true;
        showMario=true;
      }
    }
    return (
      <Square key={new Date().getTime()} showMario={showMario} showMushroom={showMushroom}/>
    );
  }

  generatePairingFunction(a,b){
    return (((a+b)*(a+b+1))/2)+b;
  }

  render() {
    return (
      <div>
        {this.state.rows}
      </div>
    );
  }
}

class Game extends React.Component {
  constructor(props){
    super(props)

  }

  render() {
    return (
      <div className="game">
        <div className="game-board">
          <Board />
        </div>
        <div className="game-info">
          <div>{/* status */}</div>
          <ol>{/* TODO */}</ol>
        </div>
      </div>
    );
  }
}

// ========================================

ReactDOM.render(
  <Game />,
  document.getElementById('root')
);

2 个答案:

答案 0 :(得分:3)

您必须bind调用准确的this上下文,因为回调是在另一个上下文中调用的。

document.addEventListener('keydown',this.handleKey.bind(this),false);

您可能会在未来遇到有关this背景的更多问题。我建议您花些时间阅读更多相关信息。从长远来看,它可以节省您的时间。 : - )

答案 1 :(得分:3)

您可以在构造函数中定义

constructor(props){
  super(props)
    this.state={
      showMushroom:props.showMushroom,
      showMario:props.showMario,
    }   
  this.handleKey = this.handleKey.bind(this)
}