S
SolidJS8mo ago
Strange

Refs to children elements?

Quick one. Could have multiple answers. I have a passthrough component that renders two children elements in a specific layout. I want to grab refs to these two child elements. Currently the way that I am rendering these two child elements are just by props.children[0] and props.children[1], but that doesn't give me a slot to stick a couple of refs in them. How would I go about doing that?
12 Replies
Strange
StrangeOP8mo ago
I have thought about: instead of accepting child elements the standard way, maybe instead put props on the layout element that accept JSX.Elements, which I can then put refs on. hm. actually now that i try to implement that idea, i'm up against the same issue unless i just do something like let elementOne = props.children[0] ? but that's not really a ref to the underlying div, that's just a reference to the JSX.Element this is my code for those curious as to if this is more an xy problem:
import { JSX, Match, Switch } from "solid-js";
import SplitLine from "./SplitLine";

type SplitableProps = {
type: "horizontal" | "vertical",
children: [JSX.Element, JSX.Element]
}

/**
* Render two elements that can be split horizontally or vertically.
* @param props If the type is "horizontal", the children will be rendered side by side. If the type is "vertical", the children will be rendered one on top of the other.
* @returns {JSX.Element}
*/
export default function Splitable(props: SplitableProps) {
return (
<Switch fallback={<FallbackComponent />}>
<Match when={props.type === "vertical"}>
<div style={{ display: "flex", "flex-direction": "column", flex: 1 }}>
{props.children[0]}
<SplitLine type="vertical" />
{props.children[1]}
</div>
</Match>
<Match when={props.type === "horizontal"}>
<div style={{ display: "flex", "flex-direction": "row", flex: 1 }}>
{props.children[0]}
<SplitLine type="horizontal" />
{props.children[1]}
</div>
</Match>
</Switch>
);
}

function FallbackComponent() {
return (
<div>
<h1>Error</h1>
<p>You should not see this component</p>
</div>
);
}
import { JSX, Match, Switch } from "solid-js";
import SplitLine from "./SplitLine";

type SplitableProps = {
type: "horizontal" | "vertical",
children: [JSX.Element, JSX.Element]
}

/**
* Render two elements that can be split horizontally or vertically.
* @param props If the type is "horizontal", the children will be rendered side by side. If the type is "vertical", the children will be rendered one on top of the other.
* @returns {JSX.Element}
*/
export default function Splitable(props: SplitableProps) {
return (
<Switch fallback={<FallbackComponent />}>
<Match when={props.type === "vertical"}>
<div style={{ display: "flex", "flex-direction": "column", flex: 1 }}>
{props.children[0]}
<SplitLine type="vertical" />
{props.children[1]}
</div>
</Match>
<Match when={props.type === "horizontal"}>
<div style={{ display: "flex", "flex-direction": "row", flex: 1 }}>
{props.children[0]}
<SplitLine type="horizontal" />
{props.children[1]}
</div>
</Match>
</Switch>
);
}

function FallbackComponent() {
return (
<div>
<h1>Error</h1>
<p>You should not see this component</p>
</div>
);
}
REEEEE
REEEEE8mo ago
You can't do that. You'd probably have to use a context that the children use to register themselves
Strange
StrangeOP8mo ago
hm. not ideal. though not impossible. i already kind of have a context that does that.. sort of would there be another way of structuring my code that makes this an easier problem to solve? because i can’t think of any
thetarnav
thetarnav8mo ago
you can use the children helper to get references to elements like you wanted in op
Strange
StrangeOP8mo ago
https://docs.solidjs.com/reference/component-apis/children neat! i’ll give it a shot when i get out of calc
thetarnav
thetarnav8mo ago
ah wait you don’t want to “get refs” to children but change where they are rendered
Strange
StrangeOP8mo ago
no i do wait to get refs to them. i’ll need to be able to change the heights and widths of them based on where the SplitLine is i’ll be passing the refs of the children to SplitLine so it can do some calculations and set the new dimensions alright now that i’ve had a moment to think about this. i wonder if it would be possible to create the refs at the child component level then pass them up through the parent components is this a supported pattern? the whole thing with running once may be an issue, i don’t know if refs are reactive :eyesFinite: you can do a similar thing in react with using functions as props, then calling the functions at the child level, thus passing whatever back up the chain
REEEEE
REEEEE8mo ago
Yes thats what I meant by using a context Also to make sure the refs are reactive, use a signal to store the refs
Strange
StrangeOP8mo ago
oh i see. for whatever reason i was thinking of a context created at the root element of the entire app, now that i think about it that’s not what needs to happen just a context for each Splittable. not bad at all update: using contexts did solve this :) thanks!
Strange
StrangeOP8mo ago
REEEEE
REEEEE8mo ago
Nicee
thetarnav
thetarnav8mo ago
👍
Want results from more Discord servers?
Add your server