首页 > 解决方案 > 反应。在状态更新之前调用该函数

问题描述

我正在编写 Snake 游戏应用程序进行练习。

我有一个 changeDirection 函数,它根据箭头单击将适当的方向设置为状态:

changeDirection = event => {
  const { direction } = this.state;

  const keyPressed = event.keyCode;

  if (keyPressed === keyCodes.LEFT_KEY && direction !== "right") {
    this.setState({ direction: "left" });
  }
  if (keyPressed === keyCodes.UP_KEY && direction !== "down") {
    this.setState({ direction: "up" });
  }
  if (keyPressed === keyCodes.RIGHT_KEY && direction !== "left") {
    this.setState({ direction: "right" });
  }
  if (keyPressed === keyCodes.DOWN_KEY && direction !== "up") {
    this.setState({ direction: "down" });
  }
}

它工作正常,但问题出在另一个功能上。我正在根据方向状态更新蛇的头部位置。并且此函数每 1 秒执行一次(使用 setInterval),当方向改变时,蛇的头部不会立即改变方向。它会在下一步行动中完成。

我知道这是因为蛇第一次移动时尚未设置新的方向状态,但我不知道如何解决这个问题。

这是回购: https ://github.com/Dito-Orkodashvili/snake

标签: reactjsasynchronoussetstate

解决方案


您仅更新方向的状态。这使得组件重新渲染。然后你更新蛇的状态并且组件再次重​​新渲染,然后当你看到头部更新时。

一个解决方案可能是分解 moveSnake 函数。组件渲染后,仅使用 moveSnake 移动蛇。

创建另一个函数来更新头部和蛇状态并从键盘事件处理程序中调用它。这样,组件将同时重新渲染状态中的所有更改。

从 setInterval 更新状态也应该有效,如下所示:

newDirection;

startGame = () => {
   this.interval = setInterval(() => {
     this.moveSnake();
   }, 200);
};

changeDirection = event => {
    const keyPressed = event.keyCode;

    if (keyPressed === keyCodes.LEFT_KEY && direction !== 'right') {
      this.newDirection = 'left';
    }
    if (keyPressed === keyCodes.UP_KEY && direction !== 'down') {
      this.newDirection = 'up';
    }
    if (keyPressed === keyCodes.RIGHT_KEY && direction !== 'left') {
      this.newDirection = 'right';
    }
    if (keyPressed === keyCodes.DOWN_KEY && direction !== 'up') {
      this.newDirection = 'down';
    }
};

moveSnake = () => {
   /* do updates in the snake shape */

   this.setState({
     direction: this.newDirection,
     snake: copyOfSnake
   });
};

推荐阅读