我正在用React Hooks构建snake game。 snakeDots
状态包含蛇在板上的位置。这样,新状态取决于先前的状态(如果向右移动,它会在先前的X坐标上加上2,依此类推)。由于状态是设计上与React Hooks异步的,因此我认为使其同步的方法是使用useContext
,这就是我所做的。虽然在reducer
内放置调试器会告诉我状态正确更新(setInterval
并且reducer
有效),但snakeDots
组件可用的Snake.js
并未更新。由于一切似乎都已正确连接,因此不确定发生了什么。结果,蛇是静态的,因为坐标不变。谁能阐明一些想法?非常感谢!下面的代码:
App.js
中的代码:
import React, { useState, useEffect, useReducer } from "react";
import Snake from "./Snake";
import Food from "./Food";
import { snakeContext } from "./contexts/snakeContext";
const getRandomCoordinates = () => {
let min = 1;
let max = 98;
let x = Math.floor((Math.random() * (max - min + 1) + min) / 2) * 2;
let y = Math.floor((Math.random() * (max - min + 1) + min) / 2) * 2;
return [x, y];
};
function App() {
const [snakeDots, dispatch] = useReducer(reducer, [
[0, 0],
[2, 0]
]);
const [food, setFood] = useState(getRandomCoordinates());
const [direction, setDirection] = useState("RIGHT");
const [speed, setSpeed] = useState(200);
useEffect(() => {
setInterval(() => dispatch({ type: direction }), speed);
document.onkeydown = onKeyDown;
}, []);
function onKeyDown(e) {
e = e || window.event;
switch (e.keyCode) {
case 38:
setDirection("UP");
break;
case 40:
setDirection("DOWN");
break;
case 37:
setDirection("LEFT");
break;
case 39:
setDirection("RIGHT");
break;
default:
console.log("wrong key");
}
}
function reducer(snakeDots, action) {
switch (action.type) {
case "RIGHT":
let head = snakeDots[snakeDots.length - 1];
head = [head[0] + 2, head[1]];
snakeDots.push(head);
snakeDots.shift();
debugger
return snakeDots;
default:
throw new Error();
}
}
return (
<div className="game-area">
<snakeContext.Provider value={{ snakeDots, food }}>
<Snake />
<Food dot={food} />
</snakeContext.Provider>
</div>
);
}
export default App;
Snake.js
中的代码:
import React, { useContext } from "react";
import { snakeContext } from "./contexts/snakeContext";
export default function Snake() {
const { snakeDots } = useContext(snakeContext);
debugger
return (
<div>
{snakeDots.map((dot, i) => {
const style = {
left: `${dot[0]}%`,
top: `${dot[1]}%`
};
return <div className="snake-dot" key={i} style={style}></div>;
})}
</div>
);
}
snakeContext.js
中的代码:
import { createContext } from "react";
export const snakeContext = createContext();