Ref

I am getting an interesting error when using a ref to select a canvas. Code works but just wondering if I am using ref the right way. The error is Variable 'canvasRef' is used before being assigned.ts(2454) am I doing something wrong?
import { Show, createEffect } from "solid-js";
import { createStore } from "solid-js/store";

export default function Form() {

const [store, setStore] = createStore({
image: null,
imagePreviewURL: "",
});

let canvasRef : HTMLCanvasElement;

createEffect(() => {
console.log("imagePreviewURL changed");
if (store.imagePreviewURL) {
const ctx = canvasRef.getContext("2d");
const img = new Image();
img.onload = function() {
canvasRef.width = img.width;
canvasRef.height = img.height;
ctx!.drawImage(img, 0, 0);
}
img.src = store.imagePreviewURL;
}
})

const uploadFile = async (e: any) => {
const image = e.target.files[0];
const imagePreview = URL.createObjectURL(image);
setStore("image", image);
setStore("imagePreviewURL", imagePreview);
}

return (
<div>
<form>
<label>Select a single file </label>
<input type="file" onChange={uploadFile} accept="image/*" />
</form>
<Show when={store.imagePreviewURL}>
<canvas id="canvas" ref={canvasRef} style={{"max-width": "400px"}}></canvas>
</Show>
</div>
)
}
import { Show, createEffect } from "solid-js";
import { createStore } from "solid-js/store";

export default function Form() {

const [store, setStore] = createStore({
image: null,
imagePreviewURL: "",
});

let canvasRef : HTMLCanvasElement;

createEffect(() => {
console.log("imagePreviewURL changed");
if (store.imagePreviewURL) {
const ctx = canvasRef.getContext("2d");
const img = new Image();
img.onload = function() {
canvasRef.width = img.width;
canvasRef.height = img.height;
ctx!.drawImage(img, 0, 0);
}
img.src = store.imagePreviewURL;
}
})

const uploadFile = async (e: any) => {
const image = e.target.files[0];
const imagePreview = URL.createObjectURL(image);
setStore("image", image);
setStore("imagePreviewURL", imagePreview);
}

return (
<div>
<form>
<label>Select a single file </label>
<input type="file" onChange={uploadFile} accept="image/*" />
</form>
<Show when={store.imagePreviewURL}>
<canvas id="canvas" ref={canvasRef} style={{"max-width": "400px"}}></canvas>
</Show>
</div>
)
}
16 Replies
kevinzunigacuellar
kevinzunigacuellarOP•2y ago
I am also open for other solutions if anyone got any good ideas 💜
Brendan
Brendan•2y ago
Add "!" to make typescript happy - like
let canvasRef! : HTMLCanvasElement;
let canvasRef! : HTMLCanvasElement;
fabiospampinato
fabiospampinato•2y ago
refs that are not signals imo are just a footgun
kevinzunigacuellar
kevinzunigacuellarOP•2y ago
I am not exactly sure what you mean here, can you explain?
fabiospampinato
fabiospampinato•2y ago
The kind of ref that you are using, which is just a simple variable that "works" thanks to the transform, is too problematic because it immediately causes type issues and it flat out doesn't work in some scenarios, the thing is it's not immediately obvious when it wouldn't work, so I see it as a footgun that should be deleted. If you use a signal as a ref that always works without problems.
DaOfficialWizard🧙
how would one use a signal as a ref?
fabiospampinato
fabiospampinato•2y ago
const [ref, setRef] = createSignal<HTMLWhatever | undefined> (); <div ref={setRef} />
DaOfficialWizard🧙
using the setRef function as the ref for the div? How does that work wouldnt you want to use the ref getter
fabiospampinato
fabiospampinato•2y ago
fundamentally a ref is simply a function that is called with an element, though sometimes it can look like something else. you pass it the setter so that it calls it with the element that you want, then you access it with the getter
DaOfficialWizard🧙
thanks for answering btw - i am new to SolidJS - this week - i come from the world of React - lol xD
fabiospampinato
fabiospampinato•2y ago
Like the other kind of ref if you think about it can't possibly work with a React-like transform, you are just passing "undefined" somewhere and somehow your variable changes? Solid looks deceptively similar, but it's like a different world
REEEEE
REEEEE•2y ago
a better world too
DaOfficialWizard🧙
indeed, i am having to unlearn so much xD it's great
kevinzunigacuellar
kevinzunigacuellarOP•2y ago
I see. I will try that see how it goes. I am not sure but it its not working on my end
fabiospampinato
fabiospampinato•2y ago
Can you make a playground?
kevinzunigacuellar
kevinzunigacuellarOP•2y ago
yeah thanks for following up btw following this up it works thanks a lot. I forgot to add a () to the Accessor, my bad 😅
Want results from more Discord servers?
Add your server