我按照
StefanHayden的回答进行了操作,下面是测试代码。
创建Fabric Canvas对象
创建一个自定义钩子来返回fabricRef(Callback Refs):
const useFabric = () => {
const canvas = React.createRef(null);
const fabricRef = React.useCallback((element) => {
if (!element) return canvas.current?.dispose();
canvas.current = new fabric.Canvas(element, {backgroundColor: '#eee'});
canvas.current.add(new fabric.Rect(
{top: 100, left: 100, width: 100, height: 100, fill: 'red'}
));
}, []);
return fabricRef;
};
请注意:
最后,创建一个画布并传递引用:
function App() {
const fabricRef = useFabric();
return <canvas ref={fabricRef} width={640} height={360}/>;
}
但我们不能在其他地方使用fabricCanvas,我会在下一章节中解释。
Codepen
通过上下文共享Fabric Canvas对象
通过存储Refs可变值的上下文,我们可以在任何地方使用fabric canvas对象。
首先,我们定义上下文,它以ref作为值:
const FabricContext = React.createContext();
function App() {
return (
<FabricContext.Provider value={React.createRef()}>
<MyToolKit />
<MyFabric />
</FabricContext.Provider>
);
}
然后,我们可以在自定义钩子中使用它。我们现在不创建引用,而是在上下文中使用引用:
const useFabric = () => {
const canvas = React.useContext(FabricContext);
const fabricRef = React.useCallback((element) => {
if (!element) return canvas.current?.dispose();
canvas.current = new fabric.Canvas(element, {backgroundColor: '#eee'});
canvas.current.add(new fabric.Rect(
{top: 100, left: 100, width: 100, height: 100, fill: 'red'}
));
}, []);
return fabricRef;
};
function MyFabric() {
const fabricRef = useFabric();
return <canvas ref={fabricRef} width={640} height={360} />;
}
我们可以在任何地方使用它,只要上下文是可用的:
function MyToolKit() {
const canvas = React.useContext(FabricContext);
const drawRect = () => {
canvas.current?.add(new fabric.Rect(
{top: 100, left: 100, width: 100, height: 100, fill: 'red'}
));
};
return <button onClick={drawRect}>Draw</button>;
}
在App的整个生命周期中,现在可以在任何地方使用fabric画布对象。
Codepen
通过props共享Fabric Canvas Object
如果不想通过上下文(如全局变量)共享,我们也可以通过props与父组件共享。
CodePen
通过forwardRef共享Fabric Canvas Object
如果不想通过上下文(如全局变量)共享,我们也可以通过forwardRef与父组件共享。
CodePen