Invalid hook call error when trying to call function from other file
Unanswered
Brown bear posted this in #help-forum
Brown bearOP
Want to create button in another component but onclick to make it call the addRect within the FabricCanvas.tsx file but getting invalid hook call error. How would I be able to make the button in a separate component yet still be able to call this function?
Toolbar.tsx
FabricCanvas.tsx
Toolbar.tsx
import addRect from "./FabricCanvas";
import canvas from "./FabricCanvas";
export default function Toolbar() {
return (
<div className="fixed top-10 left-0 bottom-0 w-1/20 bg-gray-200 p-4">
<Card>
<div className="flex flex-col auto">
<Button onClick={addRect}>Rectangle</Button>
</div>
</Card>
</div>
);
}FabricCanvas.tsx
export const FabricCanvas = () => {
const [canvas, setCanvas] = useState<fabric.Canvas>();
useEffect(() => {
const c = new fabric.Canvas("canvas", {
height: window.innerHeight,
width: window.innerWidth,
backgroundColor: "white",
});
// settings for all canvas in the app
fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.cornerColor = "#2BEBC8";
fabric.Object.prototype.cornerStyle = "rect";
fabric.Object.prototype.cornerStrokeColor = "#2BEBC8";
fabric.Object.prototype.cornerSize = 6;
setCanvas(c);
return () => {
c.dispose();
};
}, []);
const addRect = (canvas?: fabric.Canvas) => {
if (!canvas) return;
const rectWidth = 200;
const rectHeight = 280;
const rect = new fabric.Rect({
left: 600,
top: 200,
height: rectHeight,
width: rectWidth,
stroke: "#2BEBC8",
fill: "transparent",
strokeUniform: true,
} as CustomRectOptions);
...1 Reply
hoist up
make some state that you keep in this component that represents the rectangles in their simplest form eg
pass down
then you can use this state to add the "real" rectangles to fabric
does that make sense?
addRect to a component (or context) that contains both FabricCanvas and Toolbarmake some state that you keep in this component that represents the rectangles in their simplest form eg
const [rectangles, setRectangles] = useState([])
function addRect() {
const newRectangle = { width: 200, height: 280 }
setRectangles(rectangles => [...rectangles, newRectangle])
}pass down
rectangles to the FabricCanvasthen you can use this state to add the "real" rectangles to fabric
useEffect(() => {
fabric.clear() // clear the canvas, idk how to actually do this in fabric
rectangles.forEach(rectangle => {
// use the width and height from the rectangle to add it to fabric
const rect = new fabric.Rect({.... etc
})
}, [rectangles])does that make sense?