反应状态已正确更新,但游戏循环函数内部除外



我有这个非常简单的反应代码,它使用 useState 钩子声明一个名为 money 的状态变量

然后我使用 useEffect 钩子触发一个游戏循环启动一次

在这个游戏循环中,我只是增加货币状态变量的值。

import React, { useState, useEffect } from "react";
export default function Game() {
// declare one state variable
const [money, setMoney] = useState(100);
// start gameloop
useEffect(() => {
let anim = requestAnimationFrame(gameloop);
return () => {
cancelAnimationFrame(anim);
};
}, []);
function gameloop() {
setMoney(money => money + 1);
console.log(money); // always returns 100
requestAnimationFrame(gameloop);
}
return (
<div>
<div>{money}</div>
</div>
);
}

UI 会正确更新,当我使用 react 开发工具查看它时,状态也会更新。

但是,在游戏循环函数中,当我执行console.log(money);时,它总是打印 100

似乎如果我尝试读取游戏循环函数中的 money 变量,它总是初始状态,而不是真实状态。

关于我在这里做错了什么的任何想法?

gameloop函数是在初始渲染中money具有值100时声明的。正是这个相同的函数,在其范围内,money变量仍然是 100,在每一帧上被调用,而不是在每个渲染上创建的函数(在money中具有"最新"值(。

要同步两个计划(rAF 与 React(,您可以使用useRef钩子。例如,在每个渲染上重新创建游戏循环:

let gameloop = useRef();
gameloop.current = function() {
...
requestAnimationFrame(gameloop.current);
}

实际上,useRef钩子在函数组件上创建一种实例属性。

你没有做错什么。这是因为 React 状态是异步更新的。这意味着,当您想要控制台记录money变量的状态时,状态尚未更新。您可以做的是从useEffect函数中记录它,如下所示:

useEffect(() => {
let anim = requestAnimationFrame(gameloop);
console.log(money);    
return () => {
cancelAnimationFrame(anim);
};
}, [money]);

相关内容

  • 没有找到相关文章

最新更新