S
SolidJS•6mo ago
Liquido

How to pass props to context reactively?

I have a context that accepts props and then provides the prop values to its consumer components:
type FormGroupProps = { hasError?: boolean, name: string, children: JSXElement };

type FormGroupContextValue = { hasError: boolean, name: string };
const FormGroupContext = createContext<FormGroupContextValue>({
hasError: false, name: ''
});

export function FormGroup(props: FormGroupProps) {
return (
<FormGroupContext.Provider
value={{ hasError: Boolean(props.hasError), name: props.name }}
>
{props.children}
</FormGroupContext.Provider>
);
}

export function useFormGroup() {
return useContext(FormGroupContext);
}

export function TestComponent() {
const group = useFormGroup();
return (
<pre>
Has error: {group.hasError}
Name: {group.name}
</pre>
)
}

// Usage
const [errorA, setErrorA] = createSignal(false);

return <>
<FormGroup name="a" hasError={errorA()}>
<TestComponent />
</FormGroup>
<button onClick={() => setErrorA(err => !err)}>Toggle error</button>
</>
type FormGroupProps = { hasError?: boolean, name: string, children: JSXElement };

type FormGroupContextValue = { hasError: boolean, name: string };
const FormGroupContext = createContext<FormGroupContextValue>({
hasError: false, name: ''
});

export function FormGroup(props: FormGroupProps) {
return (
<FormGroupContext.Provider
value={{ hasError: Boolean(props.hasError), name: props.name }}
>
{props.children}
</FormGroupContext.Provider>
);
}

export function useFormGroup() {
return useContext(FormGroupContext);
}

export function TestComponent() {
const group = useFormGroup();
return (
<pre>
Has error: {group.hasError}
Name: {group.name}
</pre>
)
}

// Usage
const [errorA, setErrorA] = createSignal(false);

return <>
<FormGroup name="a" hasError={errorA()}>
<TestComponent />
</FormGroup>
<button onClick={() => setErrorA(err => !err)}>Toggle error</button>
</>
Playground link: https://playground.solidjs.com/anonymous/d7a38bbe-fa34-49c9-9d8f-7211839257ad How do I make the props passing to the context value reactive?
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
6 Replies
Jasmin
Jasmin•6mo ago
You have to make the context values accessors: https://playground.solidjs.com/anonymous/699f142f-cfce-448e-9fbf-e66b0863391e What also works if you want to mimic solid's component prop vibe, it to make them getters: https://playground.solidjs.com/anonymous/49bdd6b3-f641-4d1c-aa1e-7a1ba5aaf12b Both these solutions make sure that the reactivity of props.value is preserved Because in your case, props.value only gets accessed once inside the context provider value property but doesn't stay reactive.
Liquido
LiquidoOP•6mo ago
I come from a lot of React work and still trying to get used to the new paradigm. Does it mean that when I call the useContext, even if the context value changes (new prop is passed), the child component does not get updated? Do I understand it correctly that, there is no concept of component updates in SolidJS, just updates happening within "tracked scopes" (in my case that tracked scopes are the JSX at top level, where I render FormGroup; and the JSX of the TestComponent)?
Jasmin
Jasmin•6mo ago
I really suggest going through the tutorial on the solid site. It teaches you all the basics :) https://www.solidjs.com/tutorial/introduction_basics Yes, components do not rerun in solidjs. Every reactive state is contained inside a function or a getter which makes the scope subscribe to the signals it depends on when called.
Liquido
LiquidoOP•6mo ago
I actually did go through the tutorial before I started my project with SolidJS but maybe it is time to revisit it again 🙂
Dakotys
Dakotys•6mo ago
Solid Playground
Quickly discover what the solid compiler will generate from your JSX template
Madaxen86
Madaxen86•6mo ago
And maybe have a look at the existing form libraries: https://modularforms.dev/solid Or https://felte.dev/docs/solid/getting-started They provide easy interfaces to interact with inputs, form validation also adapters for validation libs like zod.
Felte | Getting started | Solid
An extensible form library for Svelte, Solid and React.
Want results from more Discord servers?
Add your server