S
SolidJSā€¢3w ago
snorbi

Access ref in child component when using forwarding refs

I would like to use a forwarding ref as described in https://docs.solidjs.com/concepts/refs#forwarding-refs but also access the ref in the child component itself, like:
// Child component
function Canvas(props) {
let anotherRef // <-- how to assign this?
onMount(() => anotherRef.addEventListener('click', ...))
return (
<div className="canvas-container">
<canvas ref={props.ref} /> {/* Assign the ref to the canvas element */}
</div>
)
// Child component
function Canvas(props) {
let anotherRef // <-- how to assign this?
onMount(() => anotherRef.addEventListener('click', ...))
return (
<div className="canvas-container">
<canvas ref={props.ref} /> {/* Assign the ref to the canvas element */}
</div>
)
Is it possible?
4 Replies
peerreynders
peerreyndersā€¢3w ago
Try <canvas ref={(el) => props.ref = anotherRef = el} />
the ref is passed as a callback function.
If that doesn't work, try
<canvas ref={(el) => {anotherRef = el; props.ref(el);} />
<canvas ref={(el) => {anotherRef = el; props.ref(el);} />
snorbi
snorbiOPā€¢3w ago
It works, thanks! I'm a bit lost how refs work šŸ˜¦ What I try to achieve is to create a component which wraps various children 3-4 components deep, and to propagate the ref of the deepest component to the top level component. It is something like:
ValidatingInputFieldWithLabel
ā”œā”€ InputFieldWithLabel
ā”‚ ā”œā”€ Label
ā”‚ ā””ā”€ InputField
ā”‚ ā””ā”€ <input>
ā””ā”€ ValidationDisplay
ValidatingInputFieldWithLabel
ā”œā”€ InputFieldWithLabel
ā”‚ ā”œā”€ Label
ā”‚ ā””ā”€ InputField
ā”‚ ā””ā”€ <input>
ā””ā”€ ValidationDisplay
(I know it is not ideal from an "encapsulation" viewpoint. I have other ideas how to solve the problem but I'm very curious whether it is possible to propagate refs "upwards".) What I would like is to know the ref of the <input> at the level of ValidatingInputFieldWithLabel, so I can add event listeners to the <input>. What is the best solution? Besides, can someone explain what is the magic behind the ref feature? Until now I thought I understand it but now I'm a bit confused, e.g. how can I know that it is a simple Element or a Function? Or should I always check it at runtime in my custom components? Thanks.
peerreynders
peerreyndersā€¢3w ago
so I can add event listeners
Why not just pass those listeners down through InputFieldWithLabel and InputField as props and have InputField set the onInput etc. props?
how can I know that it is a simple Element or a Function?
I'd say it is the other around. The ref prop is part of the JSX transform. If a function is passed it is called . Otherwise it probably creates the necessary function needed to assign the variable identified at runtime. i.e. the JSX transform makes sure that <canvas ref={canvasRef} /> is actually <canvas ref={(el) => canvasRef = el} />; So the props.ref has to be a function.
snorbi
snorbiOPā€¢3w ago
Thanks @peerreynders for the detailed explanation. I will pass listeners instead, it is a much more clean solution šŸ™‚

Did you find this page helpful?