Better Way to Write This?

Hey y'all! I have some code that works, but I can't help but feel there must be a better way to write it. I have this form, and I created a Field component. Field's will only be input elements or textarea elements. The way I have it now, I create signals for the refs, then pass the signal into the Field component, which sets the ref appropriately:
let [nameRef, setNameRef] = createSignal<HTMLInputElement>();
let [emailRef, setEmailRef] = createSignal<HTMLInputElement>();
let [messageRef, setMessageRef] = createSignal<HTMLTextAreaElement>();
let [nameRef, setNameRef] = createSignal<HTMLInputElement>();
let [emailRef, setEmailRef] = createSignal<HTMLInputElement>();
let [messageRef, setMessageRef] = createSignal<HTMLTextAreaElement>();
<Field
label='Name'
name='name'
type='text'
placeholder='Your Name...'
setRef={setNameRef}
/>
<Field
label='Email'
name='email'
type='email'
placeholder='Your Email Address...'
setRef={setEmailRef}
/>
<Field
label='Message'
name='message'
type='textarea'
placeholder='Your Message...'
setRef={setMessageRef}
/>
<Field
label='Name'
name='name'
type='text'
placeholder='Your Name...'
setRef={setNameRef}
/>
<Field
label='Email'
name='email'
type='email'
placeholder='Your Email Address...'
setRef={setEmailRef}
/>
<Field
label='Message'
name='message'
type='textarea'
placeholder='Your Message...'
setRef={setMessageRef}
/>
Then, the Field component: https://sourceb.in/vtBHriCHuF Is this the best way to do this? Or is there a better option?
SourceBin
Field.tsx
Instantly share your code with the world.
2 Replies
Max
Max10mo ago
If the goal is just to collect the individual refs I think its pretty good. On the Field component pretty sure you can just pass the setRef props to the div instead of having to redeclare a ref var and setting it on mount. Refs could also be signal or store of an object, or you could just use value and setValue instead of refs if you dont need refs and just want to collect values. Not sure about the scope of youre question but in that order I would look at things.
Martnart
Martnart10mo ago
^ agree. I'd just like also point you to mergeRefs https://github.com/solidjs-community/solid-primitives/tree/main/packages/refs#mergerefs It comes in handy in situations like these.
const Main = () => {
let nameRef: HTMLInputElement | undefined

return <Field ref={nameRef} />
}

const Field = <T>(props: { ref: Ref<T> }) => {
let ref: T

return <input ref={mergeRefs(props.ref, el => (ref = el))} />
}
const Main = () => {
let nameRef: HTMLInputElement | undefined

return <Field ref={nameRef} />
}

const Field = <T>(props: { ref: Ref<T> }) => {
let ref: T

return <input ref={mergeRefs(props.ref, el => (ref = el))} />
}