I'm trying to 'move' in my 10x10 grid by updating the activeCellId state. However none of the methods I tried works. This is my code.
const GridCells: React.FC = () => {
const gridArray = [...Array(100).keys()];
const color = [
"bg-slate-50",
"bg-slate-100",
"bg-slate-200",
"bg-slate-300",
"bg-slate-400",
"bg-slate-500",
"bg-slate-600",
"bg-slate-700",
"bg-slate-800",
"bg-slate-900",
];
const [activeCellId, setActiveCellId] = useState(42);
// useEffect(() => {
// document.addEventListener("keydown", updateActiveCellId, false);
// }, []); // this doesn't work. the activeCellId is only incremented once, and afterwards the setActiveCellId doesn't get called at all
const updateActiveCellId = (e: React.KeyboardEvent) => {
// will eventually be a switch case logic here, for handling arrow up, left, right down
console.log(activeCellId);
setActiveCellId(activeCellId + 1);
};
return (
<div
className="grid-rows-10 grid grid-cols-10 gap-0.5"
// onKeyDown={updateActiveCellId} this also doesn't work
>
{gridArray.map((value, id) => {
const colorId = Math.floor(id / 10);
return (
<div
key={id}
className={
"h-10 w-10 "
+ color[colorId]
+ (id === activeCellId ? " scale-125 bg-yellow-400" : "")
}
>
{id}
</div>
);
})}
</div>
);
};
I'm trying to update a state in the react component by pressing certain keys. I've tried UseEffect with [] dep array and tried onKeyDown and it also doesn't work. I also tried following this useRef way it doesn't work too.
const innerRef = useRef(null);
useEffect(() => {
const div = innerRef.current;
div.addEventListener("keydown", updateActiveCellId, false);
}, []); // this doesn't work at all
const updateActiveCellId = (e: React.KeyboardEvent) => {
console.log(activeCellId);
setActiveCellId(activeCellId + 1);
};
return (
<div
className="grid-rows-10 grid grid-cols-10 gap-0.5"
ref={innerRef}
>
...
)
Try this:
useEffect(() => {
document.addEventListener("keydown", updateActiveCellId, false);
return () => {
document.removeEventListener("keydown", updateActiveCellId, false);
}
}, [activeCellId]);
The [activeCellId]
is the dependency of useEffect
. Everytimes activeCellId
changes, the function inside useEffect
will run.
You had an empty dependency, so it ran on initial component mount only.
The returned function containing removeEventListner
is executed when the component unmounts (See cleanup function in the docs). That is to ensure you have only one event listener runnign at once.