I am working through the following code:
class Canvas extends React.Component {
componentDidMount() {
const canvas = this.refs.canvas;
const ctx = canvas.getContext("2d");
const img = this.refs.image;
img.onload = () => {
ctx.drawImage(img, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(this.props.text, 210, 75); // THIS IS THE PLACE TEXT IS EMBEDDED INTO THE PICTURE
};
}
render() {
return (
<div>
<canvas ref="canvas" width={640} height={425} />
<img
ref="image"
alt="Stackoverflow56203352"
src={backImg}
className="hidden"
/>
</div>
);
}
}
I am trying to convert it to functional form and my effort has been so far stalled due to lack of replacement of getContext
.
i.e my try here:
const Canvas = ({}) => {
const canvas = useRef("")
const ctx = canvas.getContext("2d")
const img = useRef("")
img.onload = () => {
ctx.drawImage(img, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(this.props.text, 210, 75); // THIS IS THE PLACE TEXT IS EMBEDDED INTO THE PICTURE
};
return (
<div>
<canvas ref="canvas" width={640} height={425} />
<img
ref="image"
alt="Stackoverflow56203352"
src={backImg}
className="hidden"
/>
</div>
);
}
doesn't cut it.
The complete sandbox code is at this location
The main change is that you need to do your wiring up in useEffect
, ensuring to use .current
to access the current ref for your canvas and image.
Originally I thought it would work with only a single useEffect
but it failed on reloading the page (I think due to the image being cached and not triggering onload
again). Adding a second useEffect
has solved it (thanks to Dennis Vash for the catch):
const Canvas = props => {
const canvas = useRef(null);
const image = useRef(null);
useEffect(() => {
const ctx = canvas.current.getContext("2d");
image.current.onload = () => {
ctx.drawImage(image.current, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(props.text, 210, 75);
};
}, []);
useEffect(() => {
const ctx = canvas.current.getContext("2d");
ctx.drawImage(image.current, 0, 0);
ctx.font = "40px Courier";
ctx.fillText(props.text, 210, 75);
});
return (
<div>
<canvas ref={canvas} width={640} height={425} />
<img
ref={image}
alt="Stackoverflow56203352"
src={backImg}
className="hidden"
/>
</div>
);
};
Also, use {}
around your refs (not quotes).
Updated sandbox using two useRef
hooks here
Try to refresh the page couple of times
Using your code the text on image vanishes. I have given a sandbox link in the question.
have updated... ideally the rendering code should be moved into a separate useCallback but it's working now.
I added the font rendering back in to the 'onload' of the first
useEffect
and removed theprops.text
dependency limitation from the second one.Thanks!! big help