Объясните что не так с useState, useEffect в моём коде

хочу написать простую игру "змейка" на React.js с помощью функциональных компонентов. Часть когда уже готова, но столкнулся с багом, при перемещении змейки по полю, змейка дёргается назад, в место предыдущих координат, не могу понять из-за чего, объясните пожалуйста в чём проблема и как её исправить.

import React, { useState, useEffect } from 'react';
import Snake from './Snake';

function App() {

  const [snakeDots, setSnakeDots] = useState([[0, 0], [2, 0]]); // Координаты спавна змейки в начале игры
  const [direction, setDirection] = useState('RIGHT');

  useEffect(() => {
    setInterval(moveSnake, 200); // Указываем скорость перемещения змейки
    document.onkeydown = onKeyDown;
  })
  
  // Задаём направление движения для змейки
  let onKeyDown = (e) => {
    e = e || window.event;
    switch (e.keyCode) {
      case 38:
        setDirection('UP');
        break;
      case 40:
        setDirection('DOWN');
        break;
      case 37:
        setDirection('LEFT');
        break;
      case 39:
        setDirection('RIGHT');
        break;
    }
  }

  let moveSnake = () => {
    let dots = [...snakeDots];
    let head = dots[dots.length - 1];

    switch (direction) {
      case 'RIGHT':
        head = [head[0] + 2, head[1]];
        break;
      case 'LEFT':
        head = [head[0] - 2, head[1]];
        break;
      case 'DOWN':
        head = [head[0], head[1] + 2];
        break;
      case 'UP':
        head = [head[0] + 2, head[1] - 2];
        break;
    }
    dots.push(head); // Добавляем новые координаты
    dots.shift(); // Удаляем старые координаты
    setSnakeDots(dots); // Сетим координаты для змейки
  }

  return (
    <div className="game-area">
      <Snake snakeDots={snakeDots} />
    </div>
  );
}

export default App;

Код компонента змейки выглядит вот так:

import React from 'react';

function Snake(props) {

    return (
        <div>
            {props.snakeDots.map((dot, i) => {
                const style = {
                    left: `${dot[0]}%`,
                    top: `${dot[1]}%`,
                }
                return (
                    <div className='snake-dot' key={i} style={style}></div>
                )
            })}
        </div>
    );
}

export default Snake;

Так же добавлю ссылку на гитхаб https://github.com/Miltosh/The-Game-Snake.github.io

UPD:

Заметил, что проблема скорее всего в этом участке кода

 let moveSnake = () => {
    ...
// До этого момента код работает как положено, сработка идёт каждых 200 мс, как задано в константе
    setSnakeDots(dots); 
// На этом этапе интервал начинает "ускоряться" и срабатывать быстрее положенного, но не могу понять почему
  }

Ответы (1 шт):

Автор решения: Konstantin Modin

Попробуй написать useEffect так:

useEffect(() => {
  setInterval(moveSnake, 200); // Указываем скорость перемещения змейки
  document.onkeydown = onKeyDown;
}, [moveSnake, onKeyDown])
→ Ссылка