javascript - React.js - 如何停止 setInterval 并在单击后恢复它

标签 javascript reactjs ecmascript-6 setinterval mount

我正在使用 React.js 开发 Game of Life。到目前为止一切正常,但我想添加额外的功能,允许停止游戏(循环)并在需要时恢复游戏。我不知道该怎么做。因此,在主类中,我有一个方法/函数来启动游戏,并在单击 render() 中定义的按钮后触发:

  constructor(props) {
    super(props);
    this.state = {cellStates: Array(TOTAL_FIELDS).fill(0), cellID: Array(TOTAL_FIELDS), gameRunning: false, counter: 0}; //set and fill initial states

    this.changeState = this.changeState.bind(this);

    this.resetGame = this.resetGame.bind(this);
    this.startGame = this.startGame.bind(this);
    this.stopGame = this.stopGame.bind(this);
    this.showGameStatus = this.showGameStatus.bind(this);

    for (let o = 1; o <= TOTAL_FIELDS; o++)
    {
      this.state.cellID[o-1] = o;
    }
  }

startGame() {
    function checkZeros(arr) { //check if board is blank
      return arr === 0;
    }

    if (!this.state.cellStates.every(checkZeros)) {
      alert ('Game starts!');
      let cycle = this.state.counter; //define number of life cycle

      this.setState(() => {
        return {
          gameRunning: true //game is on
        };
      });

      $('#reset-button').attr("disabled", "disabled");
      $('#start-button').attr("disabled", "disabled");
      $('#stop-button').removeAttr("disabled"); //handle buttons


      let goGame = setInterval(() => {
        const newStates = [];

        for (let x = 0; x < TOTAL_FIELDS; x++) {
          if (this.state.cellStates[x] === 0) {  //cell is dead
            if (this.calculateCellsAround(x) === 3)
            {
              newStates.push(1);
            }
            else {
              newStates.push(this.state.cellStates[x]);
            }
          }
          else {  //cell is alive
            if (this.calculateCellsAround(x) === 3 || this.calculateCellsAround(x) === 2)
            {
              newStates.push(this.state.cellStates[x]);
            }
            else {
              newStates.push(0);
            }
          }
        }
        this.setState(() => {
            return {cellStates: newStates, counter: cycle++};
        });
      }, 50);
    }
    else {
      alert ("Please fill at least one cell to launch a game.")
    }
  }

  render() {
    return (
      <div style={{marginTop:0+"px"}} key="wrap-it-all">
        <Header />
        <Grid>
          <Row>
            <Col md={12}>
              <div className="board-outline">
                {this.createMap(140, TOTAL_FIELDS)}
              </div>
            </Col>
          </Row>
          <Row>
            <Col md={12}>
              <button id="start-button" onClick={() => this.startGame()}>Start</button>
              <button id="stop-button" onClick={() => this.stopGame()}>Stop</button>
              <button id="reset-button" onClick={() => this.resetGame()}>Reset</button>
              <p style={{color:`#fff`}}>Lifecycle: <span className="lifecycle">{this.state.counter}</span>. Game is <span className="gamerun">{this.showGameStatus()}</span>.</p>
              <Alert className="disclaimer" bsStyle="warning">
                <strong>Instruction:</strong> Select the initial state of cells and press the [Start] button.
              </Alert>
            </Col>
          </Row>
        </Grid>
      </div>
    );
  }

我认为这一切都与挂载/卸载内置函数有关,但我不知道如何使用它们才能使其全部正常工作。

最佳答案

您需要在停止时使用 clearInterval(handle) 取消间隔。 如果您想恢复,只需再次使用 setInterval(callback, ti​​ck) 即可。

此外,只需将您的匿名函数(又名 setInterval(() => {...}) 更改为

function onTimerTick() {
   //copy everything marked as "..." here
}

并使用setInterval(onTimerTick, 50)

关于javascript - React.js - 如何停止 setInterval 并在单击后恢复它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48658880/

相关文章:

javascript - 你如何只显示一次 JS 警报?

javascript - 使用jquery的div中的元素数量

javascript - Toggle 方法删除文本突出显示,最终阻止 execCommand 更改突出显示的文本颜色

javascript - 当我更新列表作为其依赖项时,React useEffect 有时不会触发

javascript - react : Transitions are cut after element re-render further in the elements array

reactjs - 将类组件(具有本地状态)转换为无状态功能组件和容器

javascript - Promise { <state> : "pending" } - Should we use . 那么在 async/await 之后?使困惑

javascript - 单页网络应用中的 Google Analytics trackevent

javascript - ES2015 构造函数的返回值是什么?

javascript - 导入模块的最佳实践是什么?