fabricjs的mouse事件无法获取到useState改变的状态?

复现链接

有个布尔类型的useState,点击页面上的按钮后更新,但是打印发现在canvas.on监听的mouse事件中并没有更新,还是false,将变量直接当做参数传给监听事件依然是false

阅读 1.7k
1 个回答

第一眼我以为是个简单的变量捕获造成的闭包陷阱

但是加了个 useCallback 测试之后,发现我的用例不得行🤣,而useEffect不给 deps ,所以暗戳戳地把第一版答案删掉了。

现在我觉得可能是 Fabric 的事件机制导致的问题

因为如果是普通的 DOM 事件监听:

useEffect(() => {
  const canvasElement = document.auerySelector('canvas') as HTMLCanvasElement;
  canvasElement.onclick = canvasMouseDown;

  return () => {
    canvasElement.onclick = null;
  }
})

这样是可以的,因为 useEffect 不加 deps 参数,它会在 visible 变化的时候更新副作用。
但是换成FabricJS 的事件监听就行不通了:

  const fabricRef = useRef<fabric.Canvas>();

  useEffect(() => {
    // 因为 fabric 的创建也属于副作用,但如果把它当成副作用每次清理的话,再创建的
    // 开销会很大,所以用 ref 保留首次初始化的引用
    if (!fabricRef.current) {
      fabricRef.current = new fabric.Canvas("canvas", {
        height: 600,
        width: 600,
        backgroundColor: "#ff0000"
      });
    }
    canvas = fabricRef.current;
    canvas.on("mouse:down", canvasMouseDown);

    return () => {
      canvas.off("mouse:down", canvasMouseDown);
    };
  });

就不行了。

如果蹲不到其他大佬的答案的话

或许你只能采用下面这种“奇技淫巧”了:

  const visibleRef = useRef<boolean>();
  const canvasMouseDown = (e: any) => {
    console.log("canvasMouseDown---event---->", e);
    console.log("canvasMouseDown--->", visibleRef.current);
  };
  visibleRef.current = visible;
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题