我跟着StefanHayden的回答,这里是测试代码。
创建织物画布对象
创建一个自定义钩子以返回一个 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'}
));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return fabricRef;
};
注意:
最后,创建一个画布并传递 ref:
function App() {
const fabricRef = useFabric();
return <canvas ref={fabricRef} width={640} height={360}/>;
}
但是我们不能在其他地方使用fabricCanvas,我会在下一章解释。
密码笔
按上下文共享 Fabric Canvas 对象
通过存储Refs 可变值的Context,我们可以在任何地方使用织物画布对象。
首先,我们定义上下文,它以 ref 为值:
const FabricContext = React.createContext();
function App() {
return (
<FabricContext.Provider value={React.createRef()}>
<MyToolKit />
<MyFabric />
</FabricContext.Provider>
);
}
然后,我们可以在自定义钩子中使用它。我们现在不创建 ref,而是在上下文中使用 ref:
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'}
));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
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 Canvas Object
如果不想通过 Context 共享,比如全局变量,我们也可以通过 props 与父级共享。
代码笔
通过 forwardRef 共享 Fabric Canvas 对象
如果不想通过 Context 共享,比如全局变量,我们也可以通过 forwardRef 与 parent 共享。
代码笔