我正在尝试将 React 和 FabricJ 结合起来,但我陷入了困境。
这是我的代码
import React, { useState, useEffect, useRef } from 'react';
import { fabric } from "fabric";
function App() {
const [canvas, setCanvas] = useState('');
useEffect(() => {
setCanvas(initCanvas());
}, []);
const initCanvas = () => (
new fabric.Canvas('canvas', {
height: 800,
width: 800,
backgroundColor: 'pink' ,
selection: false,
renderOnAddRemove: true,
})
)
canvas.on("mouse:over", ()=>{
console.log('hello')
})
return (
<div >
<canvas id="canvas" />
</div>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
问题是 canvas.on,因为它会导致错误“未捕获的类型错误:canvas.on 不是函数”请告诉我我在这里做错了什么
实际上问题是你试图在它是(初始状态)canvas.on中的空字符串时调用canvas
由于我们只需要创建fabric.Canvas一次,我建议将实例存储为React.useRef
我在这里为您创建了一个示例:
--> https://codesandbox.io/s/late-cloud-ed5r6q?file=/src/FabricExample.js
还将在此处显示示例组件的来源:
import React from "react";
import { fabric } from "fabric";
const FabricExample = () => {
const fabricRef = React.useRef(null);
const canvasRef = React.useRef(null);
React.useEffect(() => {
const initFabric = () => {
fabricRef.current = new fabric.Canvas(canvasRef.current);
};
const addRectangle = () => {
const rect = new fabric.Rect({
top: 50,
left: 50,
width: 50,
height: 50,
fill: "red"
});
fabricRef.current.add(rect);
};
const disposeFabric = () => {
fabricRef.current.dispose();
};
initFabric();
addRectangle();
return () => {
disposeFabric();
};
}, []);
return <canvas ref={canvasRef} />;
};
export default FabricExample;
Run Code Online (Sandbox Code Playgroud)
在初始渲染期间,您的canvas变量被设置为初始状态,''从useState(''). 直到此之后您useEffect才会运行并更新状态值。
建议:将事件处理程序移至 useEffect 中,并使用ref画布值的替代状态。refs 具有直接可变的属性,并且不需要重新渲染即可使用它们的新值。
import React, { useState, useEffect, useRef } from 'react';
import { fabric } from "fabric";
function App() {
const canvas = useRef(null);
useEffect(() => {
canvas.current = initCanvas();
canvas.current.on("mouse:over", () => {
console.log('hello')
});
// destroy fabric on unmount
return () => {
canvas.current.dispose();
canvas.current = null;
};
}, []);
const initCanvas = () => (
new fabric.Canvas('canvas', {
height: 800,
width: 800,
backgroundColor: 'pink' ,
selection: false,
renderOnAddRemove: true,
})
);
return (
<div >
<canvas ref={canvas} />
</div>
);
}
export default App;
Run Code Online (Sandbox Code Playgroud)
值得注意的是,如果您不需要组件中其他地方的画布引用,则不需要使用状态或引用,并且可以在useEffect.
useEffect(() => {
const canvas = initCanvas();
canvas.on("mouse:over", () => {
console.log('hello')
});
// destroy fabric on unmount
return () => {
canvas.dispose();
};
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7540 次 |
| 最近记录: |