Compound fields
Using fieldsets, we can create independent groups of fields, allowing us to interact with this group of fields almost like a form, or it can be perceived as lenses.
import { bindField, reatomComponent } from '@reatom/react'import { reatomField, reatomFieldSet, wrap, throwAbort } from '@reatom/core'
const toNumber = (value: string) => { const parsed = Number(value) return isNaN(parsed) ? throwAbort() : parsed}
const reatomMinMaxFieldSet = (name: string) => { const min = reatomField(0, { name: `${name}.min`, fromState: (state) => state.toString(), toState: toNumber, validate: ({ state }) => state > max() ? 'Min must be less than max' : undefined, validateOnBlur: true, })
const max = reatomField(100, { name: `${name}.max`, fromState: (state) => state.toString(), toState: toNumber, validate: ({ state }) => state <= 0 ? 'Max must be greater than 0' : undefined, validateOnBlur: true, })
return reatomFieldSet({ min, max }, name)}Now we can interact with these fields as a single unit, calculating focus and validation states for all fields at once, or even resetting the value of each field with a single call to the reset method.
const minMaxFieldSet = reatomMinMaxFieldSet('minMaxFieldSet')
const Fields = reatomComponent(() => ( <fieldset> <input {...bindField(minMaxFieldSet.fields.min)} /> <input {...bindField(minMaxFieldSet.fields.max)} /> {minMaxFieldSet.focus().dirty && ( <button onClick={wrap(() => minMaxFieldSet.reset())}>Reset</button> )} {minMaxFieldSet.validation().errors && ( <span>{minMaxFieldSet.validation().errors[0]?.message}</span> )} </fieldset>))