You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用Fabric.js创建的对象无法拖动,请求技术帮助

问题

在React应用中使用Fabric.js库,按照教程在画布上添加了黄色矩形,矩形显示正常,但无法拖动该矩形。以下是我的代码:

import React, { useState, useEffect } from "react";
import { fabric } from "fabric";
import "./App.css";
const App = () => {
  const [canvas, setCanvas] = useState("");
  useEffect(() => {
    setCanvas(initCanvas());
  }, []);
  const initCanvas = () =>
    new fabric.Canvas("canvas", {
      height: 800,
      width: 800,
      backgroundColor: "lightgray",
      selection: true
    });

  const addRect = (canvi) => {
    const rect = new fabric.Rect({
      height: 280,
      width: 200,
      fill: "yellow",
      selectable: true
    });
    canvi.add(rect);
    canvi.renderAll();
  };

  return (
    <div>
      <h1>Fabric.js on React - fabric.Canvas('...')</h1>
      <button onClick={() => addRect(canvas)}>Rectangle</button>
      <canvas id="canvas" />
    </div>
  );
};

export default App;
解决方案

问题核心是用useState存储Fabric.js的Canvas实例不合适。useState针对可序列化的状态值设计,而Canvas是包含事件绑定等内部状态的复杂对象,用useState管理会丢失关键交互能力。

改用useRef存储Canvas实例即可解决,useRef专门用于保存无需触发重渲染的可变值,能完整保留实例的所有属性和方法:

import React, { useRef, useEffect } from "react";
import { fabric } from "fabric";
import "./App.css";

const App = () => {
  const canvasRef = useRef(null);

  useEffect(() => {
    canvasRef.current = new fabric.Canvas("canvas", {
      height: 800,
      width: 800,
      backgroundColor: "lightgray",
      selection: true
    });
  }, []);

  const addRect = () => {
    const rect = new fabric.Rect({
      height: 280,
      width: 200,
      fill: "yellow",
      selectable: true
    });
    canvasRef.current.add(rect);
    canvasRef.current.renderAll();
  };

  return (
    <div>
      <h1>Fabric.js on React - fabric.Canvas('...')</h1>
      <button onClick={addRect}>Rectangle</button>
      <canvas id="canvas" />
    </div>
  );
};

export default App;

关键改动说明

  • 替换useState为useRef:useRef.current可安全存储复杂对象,不会因状态更新导致实例丢失内部交互状态。
  • 直接从canvasRef.current获取实例:确保添加矩形时使用的是同一个完整的Canvas对象,保留所有交互能力。
  • 简化addRect函数:无需传递Canvas实例参数,直接读取ref即可。

修改完成后,矩形就能正常拖动交互。

内容的提问来源于stack exchange,提问作者NightCoder101

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:22:44