Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

React setStates only updates state once and resets it

Hello im kinda new to React
im trying to make a kinda snake game, but im struggling at the movement.

the x and y value are never realy changed he is only able to move a like 1 gridcell but when i press another key he jsut goes to the starting position and goes 1 cell in the other direction.. what am i missing?

function App() {

    const [_x, setX] = useState(0);
    const [_y, setY] = useState(0);

    let lastPressedKey = '';
    let gameTicker = null;


    function triggerMovement(x, y) {
        if (lastPressedKey === 100)
            move(10, 0);

        if (lastPressedKey === 97)
            move(-10, 0);

        if (lastPressedKey === 119)
            move(0, 10);

        if (lastPressedKey === 155)
            move(0, -10);
    }

    function move(x, y){
        console.log(lastPressedKey);
        console.log(x, _x, y, _y);
        setX(_x + x);
        setY(_y + y);
    }

    function handleKeyEvent(event) {
        lastPressedKey = event.keyCode;
    }

    function startTimer() {
        gameTicker = setInterval(triggerMovement, 1000);
    }

    function clearTimer() {
        clearInterval(gameTicker)
    }

    const element = (
        <div>
            <Screen farbe="darkslategray">
                <Snake x={_x} y={_y} farbe="red"/>
            </Screen>
            <button onClick={startTimer} style={{
                bottom: 5,
                position: 'absolute'
            }}>
                Start Game
            </button>
            <button onClick={clearTimer} style={{
                bottom: 5,
                left: 625,
                position: 'absolute'
            }}>
                StopGame
            </button>
        </div>
    )

    window.addEventListener('keypress', handleKeyEvent, true);

    return element;
}

function Snake(props){

    const [x, setX] = useState(250);
    const [y, setY] = useState(250);
    let speed = props.speed;

    const element = (
        <div style={{
            width: 10,
            height: 10,
            backgroundColor: props.farbe,
            position: 'absolute',
            left: props.x,
            bottom: props.y
        }}>

        </div>
    )
    return element;
}

Really trying to get behind this, but I’m trying to get this snake to move since this morning idk what I’m missing here.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The console logs are always

10, 0 , 0 , 0
10, 0 , 0 , 10
10, 0 , 0 , 0 ... 

>Solution :

It is because of stale closures.

Here

function move(x, y){
    console.log(lastPressedKey);
    console.log(x, _x, y, _y);
    setX(_x + x);
    setY(_y + y);
}

_x and _y are referencing values from the render in which you called the startTimer function.

You can use functional form of setState to avoid this problem:

setX(ps => ps+x)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading