useField

To make it easier to create new bound input components, the useField hook provides most of the functionality needed.

The first parameter is the name of the field you want to bind a component to, while the second (optional) parameter is a data object to bind. If no data object is specified, the hook will try to find a data object in the data object context.

The return value of the hook is an object with these properties:

  • dataObject - A reference to the data object we are binding a component to

  • error - If we failed to set the data object field value, this property will contain the error, otherwise it will be null

  • setValue - The function that updates the data object field value. It takes a value, or a change event of the HTML input element

  • value - The current value stored in the data object

  • onKeyDown - A key down event handler that can be set on the input component. It will restore the saved value if the user clicks Escape while the input has focus

  • onChange - A change event handler that can be passed to the component. If the component doesn't match the onChange signature, setValue should be used instead

  • record - The current row of the data object

  • reset - Restore the saved value for the bound field in the data object

Usage

As an example, this is the implementation of BoundTextField in the appframe-mui package:

import { forwardRef } from "react";

import { TextField, TextFieldProps } from "@mui/material";
import { useField } from "@olenbetong/appframe-react";

export type BoundTextFieldProps = TextFieldProps & {
  field: string;
};

export const BoundTextField = forwardRef<HTMLInputElement, BoundTextFieldProps>(
  function BoundTextField({ field, ...props }, ref) {
    let { error, value, onChange, onKeyDown } = useField<any, any>(field);

    if (props.type === "date" && value instanceof Date) {
      value = value.toISOString().split("T")[0];
    } else if (
      ["datetime", "datetime-local"].includes(props.type ?? "") &&
      value instanceof Date
    ) {
      value = value.toISOString();
    }

    return (
      <TextField
        error={!!error}
        fullWidth
        {...props}
        helperText={error ?? props.helperText}
        value={value ?? ""}
        onChange={onChange}
        onKeyDown={onKeyDown}
        inputRef={ref}
        InputLabelProps={{
          ...props.InputLabelProps,
          shrink: !!props.value ? true : props.InputLabelProps?.shrink,
        }}
      />
    );
  }
);

API

Last updated

Was this helpful?