我正在阅读这篇文章,但不确定最终的hook是如何工作的。
以下是代码:
const useAnimationFrame = (callback) => {
const requestRef = useRef();
const previousTimeRef = useRef();
const animate = (time) => {
if (previousTimeRef.current !== undefined) {
const deltaTime = time - previousTimeRef.current;
callback(deltaTime);
}
previousTimeRef.current = time;
requestRef.current = requestAnimationFrame(animate);
};
useEffect(() => {
requestRef.current = requestAnimationFrame(animate);
return () => cancelAnimationFrame(requestRef.current);
}, []);
}
并且可以以以下方式进行使用:
const [count, setCount] = useState(0);
useAnimationFrame((deltaTime) => {
setCount((prevCount) => {
return prevCount + 1;
});
});
好的,目标是每帧递增一个数字值。
我可以解释一下运行此代码时发生了什么:
the component create a local state with
useState(0)
then the
useAnimationFrame
hook is called using this callback as parameter:(deltaTime) => { setCount((prevCount) => { return prevCount + 1; }); }
该函数接受一个数字作为输入,并在每次调用时将状态值增加一。
useAnimationFrame
是一个接受另一个函数(回调函数)作为参数的函数。它创建了两个引用。第一次执行时(由于[]
),它调用了useEffect
。它把requestAnimationFrame
返回的时间戳保存在requestRef.current
中。requestRef.current
调用animate
函数,计算请求动画帧之间的差值,然后使用该值调用回调函数,从而调用setCount
。然后它更新当前引用的值并再次调用requestAnimationFrame
。
因此,循环应该是:
component
> count = 0
useAnimationFrame <--------------+
> requestRef = ? |
> previousTimeRef = ? |
useEffect |
animate |
> deltaTime = delta#1 |
> count = 1 |
> previousTimeRef.current = time#1 |
> requestRef.current = time#2 -------+
> requestRef.current = timestamp#1
我错了吗?