我正在尝试在 React 中制作一个简单的国际象棋游戏,并尝试在使用 React 钩子的函数组件中这样做。为了移动棋子,玩家必须点击他们想要移动的棋子,然后点击想要移动的棋子。以下是我的电路板组件的片段:
const Board = () => {
const [clicked, setClicked] = useState(false);
const [from, setFrom] = useState("");
const [to, setTo] = useState("");
...
const clickHandler = (i, j) => {
if (!clicked) {
setFrom('some_value');
setClicked(true);
...
} else {
setTo('some_value');
...
setClicked(false);
}
console.log(from + ', ' + to);
}
...
问题是由于 to
和 from
状态变量没有在我想要的时候更新。控制台输出最终看起来像:
,
some_value,
some_value, some_value
即使 console.log()
在 setFrom()
/setTo()
调用之后,to 和 from 值仅在下一次点击事件时更新。
我很确定 useState
不是我想在这里使用的钩子,但是在尝试了 useRef
和 useReducer
并遇到了类似的情况后,我一头雾水关于处理这种情况的最佳方法是什么。
答案 0 :(得分:0)
局部变量在组件渲染开始时分配时设置。而且 React 状态更新是异步的,这意味着您的组件将在几毫秒后使用新值重新渲染。
因此,如果您将 console.log(from + ', ' + to);
移到点击处理程序之外,它将在下一次渲染时执行,您应该注销您期望的值。
const Board = () => {
const [clicked, setClicked] = useState(false);
const [from, setFrom] = useState("");
const [to, setTo] = useState("");
const clickHandler = (i, j) => {
if (!clicked) {
setFrom('some_value');
setClicked(true);
...
} else {
setTo('some_value');
...
setClicked(false);
}
}
// This should now log what you expect.
console.log(from + ', ' + to);
//...
}
“我想我应该在帖子中概述这一点,但为了进行计算以验证移动,我对 else 子句中的 to
和 from
变量有逻辑。”
如果您需要在点击处理程序中设置的更新值,那么您拥有这些值,因为您只是设置了它们。您无需等待状态更新。
const clickHandler = (i, j) => {
const newFrom = 'some_value';
const newTo = 'some_other_value';
if (!clicked) {
setFrom(newFrom);
setClicked(true);
} else {
setTo(newTo);
setClicked(false);
}
console.log(calculateDistance(newFrom, newTo))
}
或者,当这两个变量发生变化时,您可以改用 useEffect
来触发一些代码。
const Board = () => {
//... state hooks
useEffect(() => {
console.log(calculateDistance(from, to))
}, [from, to])
const clickHandler = //...
}
这将在 from
或 to
来自的状态被分配新值的任何渲染之后运行。
答案 1 :(得分:0)
捕获更新状态的唯一正确方法是 useEffect 钩子,因为您正在使用功能组件。 setState 是异步操作,它会在所有同步代码之后执行。 useEffect 钩子会在状态更改后立即启动,因此您可以确保捕获最新的状态值。
// this will never show you updated state:
setState(value) // this line will be executed later
console.log(value) // shows the old state
// that's how you catch new state:
useEffect(() => {
console.log(`The new state value is ${value}`)
}, [value])
答案 2 :(得分:0)
经过更多研究,我得出的解决方案是在组件主体中使用 $('#content').load('http://localhost/HTML/acerca_de.html' , '#content');
钩子来执行移动验证和板更新,useEffect
是依赖项数组的唯一成员。
to