useField()

OneForm's <Field /> comes with a lot of props to fit all components' needs, but there's no way it'll be suitable for every existing project.

That's where useField comes into play.

This hook is meant for writing custom <Field /> components.

A better option might be useFieldData which is designed for generic unopinionated use cases.

useField is used by OneForm's Field component internally which allows you to build components using the exact same tooling in your own projects.

Props

Props in

Prop Name

Description

name

The base field name without a /.

onChange

Called when the returned valueChanged is called.

onVisit

Called when the returnedfieldVisited is called.

Props out

Prop Name

Description

errorMessages

Array of error message strings.

When changed, this value is updated.

fieldName

The OneForm field name with a /.

fieldVisited

A callback function for when a field is visited.

This expects to receive an HTMLonBlur event.

isVisited

String value of the isVisited.

value

Current field value. When changed, value is updated.

valueChanged

A callback function for when a field value changes. This expects to receive an HTMLonChange event.

When to use?

A common use case is creating your own <Field /> component.

Why though?

OneForm has opinions on how it names props passed to child components. If you want more control over this, then you'll need to create your own <Field /> component.

Here's an example of a slimmed down custom <Field /> component:

import { useField } from '@oneform/react';
import {
  Children,
  cloneElement,
  memo,
  useMemo,
} from 'react'

const CustomFieldExample = ({
  children,
  isCheckbox,
}) => {
  const {
    name,
    onBlur: onVisit,
    onChange,
    // Unless `children` is a radio button, the `value` prop should never be set.
    value: inputValue,
  } = (
    children
    .props
  )

  const {
    errorMessages,
    fieldName,
    isChecked,
    isVisited,
    updateFieldValue,
    value,
    visitField,
  } = (
    useField({
      inputValue,
      isCheckboxElement: isCheckbox,
      name,
      onChange,
      onVisit,
    })
  )

  const childProps = (
    useMemo(
      () => ({
        errorMessages,
        isChecked,
        isVisited,
        name: fieldName,
        onBlur: visitField,
        onChange: updateFieldValue,
        value,
      }),
      [
        errorMessages,
        fieldName,
        isChecked,
        isVisited,
        updateFieldValue,
        value,
        visitField,
      ],
    )
  )

  return (
    cloneElement(
      (
        Children
        .only(
          children
        )
      ),
      childProps,
    )
  )
}

const MemoizedCustomFieldExample = memo(CustomFieldExample)

export default MemoizedCustomFieldExample

The actual <Field /> component in OneForm is much more complex, but that's because it has more generic requirements. In general, you want to tier a custom <Field /> component to your project's needs based on the component structure and props naming you want to do.

Last updated