DEV Community

Cover image for React Hooks Snippet: Snake Game
Ryan Kahn (he/him)
Ryan Kahn (he/him)

Posted on

React Hooks Snippet: Snake Game

Hey all! How would you model a snake game with React Hooks? Here's how I would do it! (You can play here! and Edit here!)

The main things to look at:

  • This is written in Typescript, to assist the gist also contains the same code in JavaScript.
  • The types!
    • Snake takes place on a two dimensional grid, so we represent locations on that grid with a Coordinate type, which is a tuple of two numbers representing the x and y positions
    • The Snake itself is represented in two ways:
      • Snake: An array of coordinate arrays
      • SnakeMap: A sort of Trie built from the coordinates
      • Why both? Do you want to know where the snake is, or if the snake is in a specific place? You'll probably need to know both things at different times, so we create two structures that efficiently answer each question.
    • The Game is a combination of all the data about the snake, plus:
      • a coordinate for the food
      • the score
      • and an alive boolean
    • Finally, we need a direction to move in, so we have a union type of single characters for each cardinal Direction
  • There are three important hooks our useSnake hook calls:
    • First: It calls useReducer, reducing a Game from a Direction. This is an action packed reducer, which is the logic behind the moveSnake function.
    • Second: It calls useRef to create a persistent object to store our direction. Why useRef instead of useState? Because we don't want to re-render every time you hit a direction key, which updating a stateful value would do. We also use useCallback here to create a persistent callback to update the ref.
    • Third: It calls useEffect, which (assuming the snake is alive) sets up the interval which forms our game loop. What do we do in the loop? Move the snake in the current direction!

If snakes or games aren't your thing, but you like this style, leave a comment with what hooks snippet I should write next!

Top comments (0)