与 React 一起使用时未调用 requestAnimationFrame 回调

requestAnimationFrame callback is not being called while using with React

我正在尝试用 React 组件包装 canvas 组件并设置 requestAnimationFrame 以便能够在 canvas 上绘制动画。

我有一个简单的组件试图简单地画一个圆:

import * as React from "react";
import { useLayoutEffect, useRef } from "react";

export interface Props {}

export const Loop: React.FC<Props> = () => {
  const cv = useRef<HTMLCanvasElement>(null);
  const oldTimestamp = useRef<number>(0);

  useLayoutEffect(() => {
    let animationID = 0;

    console.log("USEEFFECT");

    const loop = (timestamp: number) => {
      let secondsPassed = (timestamp - oldTimestamp.current) / 1000;
      secondsPassed = Math.min(secondsPassed, 0.1);

      oldTimestamp.current = timestamp;

      console.log("LOOP");

      update(secondsPassed);
      draw();

      animationID = requestAnimationFrame(loop);
    };

    animationID = requestAnimationFrame(loop);

    return cancelAnimationFrame(animationID);
  }, []);

  const update = (secondsPassed: number) => {};

  const draw = () => {
    console.log("DRAW");
    const ctx = cv && cv.current && cv.current.getContext("2d");
    if (ctx) {
      ctx.beginPath();
      ctx.arc(100, 75, 50, 0, 2 * Math.PI);
      ctx.stroke();
    }
  };

  return (
    <div>
      <canvas ref={cv}></canvas>
    </div>
  );
};

我添加了三个 console.log 调用来帮助确定发生了什么。 ATM 仅记录 console.log("USEEFFECT");,但没有其他记录。在我看来 useLayoutEffect 中的 animationID = requestAnimationFrame(loop); 没有调用 loop 回调。

我认为 useLayoutEffect 中的 requestAnimationFrame 设置是正确的。

我做错了什么?

你立即取消动画帧,你应该return函数:

return () => cancelAnimationFrame(animationID)