S
SolidJS10mo ago
Mathieu

How to instruct a component to reset a state it holds?

I have a form looking like this (simplified code):
<Form>
<TextField value={store.foo} />
<Select value={store.bar} />
<TextArea value={store.baz} />
</Form>
<Form>
<TextField value={store.foo} />
<Select value={store.bar} />
<TextArea value={store.baz} />
</Form>
When submitting the form, errors can show up in red under each field. The errors are state (Signal) within the input components. How can I reset the error state (which are signals [error, setError] = createSignal('') in each input component) to empty (back to initial value '')? Note as to why I need this: the form is displayed in a dialog component, when the dialog closes and reopens, the form should reset to initial field values (this is easy as it is a store holding the values externally to the input components, so just need to reset the store to initial values) and not show any errors (this is where I struggle as the error is a signal within each component)
8 Replies
apollo79
apollo7910mo ago
Where do you define the error messages (Where does the validation happen)?
Mathieu
Mathieu10mo ago
the (generic) error messages are inside the input components. e.g. within the Select components:
setError(translate('select_option'));
setError(translate('select_option'));
The validation is triggered through a Context component (each input component "registers" itself in that context (added in an array in the context), and when the form submits, the context calls the validate function inside each input component)
thetarnav
thetarnav10mo ago
To send events to the input components you can use a simple event emitter api. Which could be passed to inputs through props, or context if the emit happens in the form component.
Mathieu
Mathieu10mo ago
is this common? I've never heard about events passed between components, that's interesting. Is there a lib available? Secondly, can't this be solved with ref in SolidJS? Like, <Form ref={formRef}> then ref.resetInputs? and export a function resetInputs in Form I remember in Svelte I was doing something similar if I recall correctly
thetarnav
thetarnav10mo ago
That’s the way to send events down the component tree. there are plenty libs for that, eg event-bus in solid-primitives. Normally if you need the component up the tree to manage the state, the state should be moved up the tree, so a lot of the times emitters are not required, but you want to keep the state in the inputs I’m assuming.
Mathieu
Mathieu10mo ago
Thank you I'll look this up! And the ref won't work because this doesn't give me access to the functions within a component?
thetarnav
thetarnav10mo ago
Depends what you expose with ref
bigmistqke 🌈
bigmistqke 🌈10mo ago
why not use the context too to trigger the reset event?
// Form
const [resets, setResets] = createSignal([]);
const addToResets = (callback: () => void) => setResets(r => [...r, callback])
const resetErrors = () => resets.forEach(reset => reset())
</formContext.Provider value={{addToReset, ...}}>

// Input
const [error, setError] = createSignal();
const context = useFormContext();
context.addToResets(() => setError())
// Form
const [resets, setResets] = createSignal([]);
const addToResets = (callback: () => void) => setResets(r => [...r, callback])
const resetErrors = () => resets.forEach(reset => reset())
</formContext.Provider value={{addToReset, ...}}>

// Input
const [error, setError] = createSignal();
const context = useFormContext();
context.addToResets(() => setError())
Want results from more Discord servers?
Add your server
More Posts