Learning React and JS, I'm trying to make simple React app that displays a grid and reacts to several events.
There are 2 events: a user can click a cell in the (blue) grid and that should move the current XPos/YPos and make it red, +turn prev pos blue again, this seems to work fine.
Another way is to press a key to move the current XPos/YPos (e.g. k=right/j=right/up/down).
I added the keypress event, but it seems to use another "fresh" state for XPos/YPos (the incoming XPos/YPos is always 10,10 which is the initial setState value, not the 'current/moved' one , interestingly i do see a red dot on 10,11 combined with the location of the previous mouse-click position (so the state of the array is updated correctly apparently, very puzzling.
import React, {useState, useEffect} from 'react';
export default function Grid(props)
{
let initMatrix=[];
const [XPos, setXPos]=useState(10);
const [YPos, setYPos]=useState(10);
const Init = (rows, cols)=>
{
for (let r=0; r<rows; r++)
{
// create row
initMatrix.push([]);
for (let c=0; c<cols; c++)
{
// add a cell / color
initMatrix[r].push("blue");
}
}
}
Init(props.rows,props.cells);
initMatrix[YPos][XPos]='red';
const [matrix,setMatrix]=useState(initMatrix);
const onClicked = (row,col)=> {
console.log(`onClicked: ${YPos}${XPos}`)
let myMatrix=[...matrix];
myMatrix[YPos][XPos]='blue';
setXPos(col);
setYPos(row);
myMatrix[row][col]='red';
setMatrix(myMatrix);
}
const useKeyPress = (key, action) => {
useEffect(() => {
function onKeyup(e) {
if (e.key === key) action();
}
window.addEventListener("keyup", onKeyup);
return () => window.removeEventListener("keyup", onKeyup);
}, []);
}
const doRight = () => {
console.log(`doRight: ${YPos}${XPos}`) // always prints 10 10
let myMatrix=[...matrix];
myMatrix[YPos][XPos]='blue';
myMatrix[YPos][XPos+1]='red';
// this "+1" does not seem to 'stick',
// everytime i press "k" it's back at position 10,10 and moves to 10,11
setXPos(XPos+1);
setMatrix(myMatrix); // the matrix does update (i see the a red cell of last click and cell 10,11 is red - 10,10 is back to blue)
};
const goRight= useKeyPress('k',doRight);
return(
<div className ="grid">
{
matrix.map((row,rowidx)=>
<div className="grid-row">{
row.map((cell,colidx)=>
<div key={rowidx+"-"+colidx} className={cell} onClick={x=>onClicked(rowidx,colidx)}>{rowidx},{colidx}
</div>)}
</div>)
}
</div>
);
}
I also see my Grid() gets called twice on every mouse click/keypress.
Interestingly: it does work fine when I use onKeyDown on my outer instead of the hook and call my goRight from there so I assume it has something to do with the useKeyPress level but not clear what's wrong, and the useKeyPress hook style seems to be the more 'React way' of doing it.