form icon indicating copy to clipboard operation
form copied to clipboard

Field reactivity (state and meta) docs

Open LeCarbonator opened this issue 9 months ago • 2 comments

This docs section should cover:

  • Use useStore to get field.state.meta
  • Why meta can get stale without them
  • Why field.state.value does not need it (or maybe it does! double check)

Can be a quick explanation, but the existing examples related to fields should reflect it.

Discussion for this issue was brought up in the celebration VOD

LeCarbonator avatar Mar 03 '25 17:03 LeCarbonator

Will this be required when accessing field from form.Field (e.g. taken from here) or only from useFormContext?

<form.Field
  name="age"
  validators={{
    onChange: ({ value }) =>
      value < 13 ? 'You must be 13 to make an account' : undefined,
  }}
>
  {(field) => (
    <>
      <label htmlFor={field.name}>Age:</label>
      <input
        id={field.name}
        name={field.name}
        value={field.state.value}
        type="number"
        onChange={(e) => field.handleChange(e.target.valueAsNumber)}
      />
      {!field.state.meta.isValid && (
        <em role="alert">{field.state.meta.errors.join(', ')}</em>
      )}
    </>
  )}
</form.Field>

karan042 avatar Jul 08 '25 06:07 karan042

Will this be required when accessing field from form.Field (e.g. taken from here) or only from useFormContext?

<form.Field name="age" validators={{ onChange: ({ value }) => value < 13 ? 'You must be 13 to make an account' : undefined, }}

{(field) => ( <> <label htmlFor={field.name}>Age: <input id={field.name} name={field.name} value={field.state.value} type="number" onChange={(e) => field.handleChange(e.target.valueAsNumber)} /> {!field.state.meta.isValid && ( {field.state.meta.errors.join(', ')} )} </> )} </form.Field>

No. If you use the callback directly within form.Field, it will be rerendered when needed. This Issue refers to Form Composition, which means you extract it into its own component. That component will persist between rerenders, and therefore needs to manage the rerendering logic itself.

<form.Field /* ... */>
  {field => {
     // this is up to date.
     return field.state.meta.isValid ? 'Yes' : 'No'
  }}
</form.Field>

<form.Field /* ... */>
   {field => {
      // you need to use useStore within YourTextField
     return <field.YourTextField  />
   }}
</form.Field>

LeCarbonator avatar Jul 08 '25 07:07 LeCarbonator