From eebbc42f3b72e04f5a18ae575821d0eec03f3b54 Mon Sep 17 00:00:00 2001 From: Prasad Rathod <30808162+prasadrathod@users.noreply.github.com> Date: Wed, 24 Mar 2021 03:08:09 +0530 Subject: [PATCH] FIX:Use Reference Hook in handleKeydown Use the Reference Hook for direction and snakeCells state in the `handleKeydown` event handler to get the latest state values --- src/Board/Board.jsx | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/Board/Board.jsx b/src/Board/Board.jsx index 802270f..68a3b96 100644 --- a/src/Board/Board.jsx +++ b/src/Board/Board.jsx @@ -1,4 +1,4 @@ -import React, {useEffect, useState} from 'react'; +import React, {useEffect, useState, useRef} from 'react'; import { randomIntFromInterval, reverseLinkedList, @@ -58,12 +58,26 @@ const Board = () => { const [snake, setSnake] = useState( new LinkedList(getStartingSnakeLLValue(board)), ); - const [snakeCells, setSnakeCells] = useState( + + const [snakeCells, _setSnakeCells] = useState( new Set([snake.head.value.cell]), ); + const snakeCellsHookRef = useRef(snakeCells); + const setSnakeCells = newSnakeCells => { + snakeCellsHookRef.current = newSnakeCells; + _setSnakeCells(newSnakeCells); + } + // Naively set the starting food cell 5 cells away from the starting snake cell. const [foodCell, setFoodCell] = useState(snake.head.value.cell + 5); - const [direction, setDirection] = useState(Direction.RIGHT); + + const [direction, _setDirection] = useState(Direction.RIGHT); + const directionHookRef = useRef(direction); + const setDirection = direction => { + directionHookRef.current = direction; + _setDirection(direction); + } + const [foodShouldReverseDirection, setFoodShouldReverseDirection] = useState( false, ); @@ -86,11 +100,7 @@ const Board = () => { const isValidDirection = newDirection !== ''; if (!isValidDirection) return; const snakeWillRunIntoItself = - getOppositeDirection(newDirection) === direction && snakeCells.size > 1; - // Note: this functionality is currently broken, for the same reason that - // `useInterval` is needed. Specifically, the `direction` and `snakeCells` - // will currently never reflect their "latest version" when `handleKeydown` - // is called. I leave it as an exercise to the viewer to fix this :P + getOppositeDirection(newDirection) === directionHookRef.current && snakeCellsHookRef.current.size > 1; if (snakeWillRunIntoItself) return; setDirection(newDirection); };