S
SolidJSβ€’2mo ago
zobweyt

Context with children(() => props.children) helper triggers an error

Hey! I've been trying to create a Stepper component in which I'd have StepperContext with its API. however, somehow I need to control the displayed children, I found the children helper but it doesn't work with context https://playground.solidjs.com/anonymous/92dca985-17bc-4cbb-b2d8-d4b95fb33a33 am I missing something?
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
73 Replies
Brendonovich
Brendonovichβ€’2mo ago
children isn't necessary in that example, it's for more advanced use cases where you would otherwise be accessing props.children more than once the reason it errors is because children is basically createMemo - it eagerly evaluates the function inside it, which happens outside of the context
zobweyt
zobweytβ€’2mo ago
but how to control the displayed child? I would like children to use context to control it for example, if the currentIndex is 0, then the first child will be shown yeah the children helper above the context provider executes all children outside of the context
bigmistqke
bigmistqkeβ€’2mo ago
you don't need the children, but for stepper.currentIndex() to be reactive you have to wrap it in jsx
bigmistqke
bigmistqkeβ€’2mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Brendonovich
Brendonovichβ€’2mo ago
in that case you would need children something like this
export function Stepper(props: ParentProps) {
const [currentIndex, setCurrentIndex] = createSignal(0);

return (
<StepperContext.Provider value={{ currentIndex }}>
<StepperInner>{props.children}</StepperInner>
</StepperContext.Provider>
);
}

function StepperInner(props: ParentProps) {
const { currentIndex } = useStepper();

const c = children(() => props.children);

return <>{c.toArray()[currentIndex()]}</>
}
export function Stepper(props: ParentProps) {
const [currentIndex, setCurrentIndex] = createSignal(0);

return (
<StepperContext.Provider value={{ currentIndex }}>
<StepperInner>{props.children}</StepperInner>
</StepperContext.Provider>
);
}

function StepperInner(props: ParentProps) {
const { currentIndex } = useStepper();

const c = children(() => props.children);

return <>{c.toArray()[currentIndex()]}</>
}
zobweyt
zobweytβ€’2mo ago
should the currentIndex be updated each second there? seems like nothing happens
bigmistqke
bigmistqkeβ€’2mo ago
no it's a timeout, not an interval
zobweyt
zobweytβ€’2mo ago
oh
bigmistqke
bigmistqkeβ€’2mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
zobweyt
zobweytβ€’2mo ago
yeah got it! thank you :)
bigmistqke
bigmistqkeβ€’2mo ago
you are welcome you can think of jsx as if it is an effect so just calling a signal inside the body of a component will not be reactive, but if you call it inside an effect/memo/jsx it will be but if the goal is to display a certain html-element from its children, you maybe don't need context:
function Stepper(props: ParentProps) {
const [currentIndex, setCurrentIndex] = createSignal(0);

const c = children(() => props.children);

return <>{c.toArray()[currentIndex()]}</>
}
function Stepper(props: ParentProps) {
const [currentIndex, setCurrentIndex] = createSignal(0);

const c = children(() => props.children);

return <>{c.toArray()[currentIndex()]}</>
}
like brendonovich showed
zobweyt
zobweytβ€’2mo ago
the goal is to give the control of current index to Steps. so you can skip a step inside a step for example inside a step...
return <>
<button type="button" onClick={() => stepper.setCurrentIndex(stepper.currentIndex() + 2)} />
</>
return <>
<button type="button" onClick={() => stepper.setCurrentIndex(stepper.currentIndex() + 2)} />
</>
bigmistqke
bigmistqkeβ€’2mo ago
instepcion so the context should pass the setter and not the getter?
export function Stepper(props: ParentProps) {
const [currentIndex, setCurrentIndex] = createSignal(0);
const c = children(() => props.children);
return (
<StepperContext.Provider value={{ setCurrentIndex }}>
{c.toArray()[currentIndex()]}
</StepperContext.Provider>
);
}
export function Stepper(props: ParentProps) {
const [currentIndex, setCurrentIndex] = createSignal(0);
const c = children(() => props.children);
return (
<StepperContext.Provider value={{ setCurrentIndex }}>
{c.toArray()[currentIndex()]}
</StepperContext.Provider>
);
}
?
zobweyt
zobweytβ€’2mo ago
oh, typo
bigmistqke
bigmistqkeβ€’2mo ago
o wait lol now i make the same mistake again haha
Want results from more Discord servers?
Add your server