如何以react-hook-form设置Select的值?

Chr*_*mer 3 reactjs material-ui react-hook-form

我正在尝试加载异步数据并使用它以带有react-hook-form的形式填充material-ui组件。我有一个TextField似乎工作正常,但我似乎无法弄清楚如何让其显示Select正确的值。

这是一个代码沙盒来演示我的问题。

我正在使用文档中推荐的方式Controller来管理:Select

  const { register, handleSubmit, control, reset, setValue } = useForm()

  <TextField name="name" inputRef={register} />
  <Controller
    name="color_id"
    control={control}
    register={register}
    setValue={setValue}
    as={
      <Select>
        {thingColors.map((tc, index) => (
          <MenuItem key={index} value={tc.id}>
            {tc.name}
          </MenuItem>
        ))}
      </Select>
    }
  />
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用 useForm() 填充字段reset,这似乎适用于 TextField。

  useEffect(() => {
    getData().then((result) => {
      reset({
        color_id: 3,
        name: 'Bill'
      });
    });
  }, [reset]);
Run Code Online (Sandbox Code Playgroud)

这似乎正确设置了表单的值,当我提交表单时,它似乎具有正确的name和值color_id。看来我没有正确连接,Select并且控件没有显示我设置的选定值。

如何让我的 Material UISelect在这里显示我的应用价值?

小智 6

在 React hook 表单的版本 7 中,您可以使用 setValue() setvalue API

useEffect(() => {
  getData().then((result) => {
    setValue('color_id', '3', { shouldValidate: true })
    setValue('name', 'Bill', { shouldValidate: true })
  });
}, []);
Run Code Online (Sandbox Code Playgroud)

请注意,我使用了 shouldValidate,这是因为我在按钮中使用了 isValidated,如下所示:

<Button
   handler={handleSubmit(handlerSignInButton)}
   disable={!isValid || isSubmitting}
   label={"Guardar"}
 />
Run Code Online (Sandbox Code Playgroud)

随着shouldValidate我重新验证输入,还有isDirty.

在react hook form的版本7中,你应该使用render而不是Controller API

<Controller
control={control}
name="test"
render={({
  field: { onChange, onBlur, value, name, ref },
  fieldState: { invalid, isTouched, isDirty, error },
  formState,
}) => (
  <Checkbox
    onBlur={onBlur}
    onChange={onChange}
    checked={value}
    inputRef={ref}
  />
)}
Run Code Online (Sandbox Code Playgroud)

/>

或者您可以使用reset重置API

useEffect(() => {
  getData().then((result) => {
    reset({
      'color_id': '3',
      'name': 'Bill'
     )
  });
}, []);
Run Code Online (Sandbox Code Playgroud)

我还没有使用 Material UI 和 React hook 形式,但希望这有帮助。

我的选择组件的示例,在 Ionic React Typescript 中:

import { ErrorMessage } from "@hookform/error-message";
import { IonItem, IonLabel, IonSelect, IonSelectOption } from 
"@ionic/react";
import { FunctionComponent } from "react";
import { Controller } from "react-hook-form";

type Opcion = {
  label: string;
  value: string;
};

interface Props {
  control: any;
  errors: any;
  defaultValue: any;
  name: string;
  label: string;
  opciones: Opcion[];
}

const Select: FunctionComponent<Props> = ({
  opciones,
  control,
  errors,
  defaultValue,
  name,
  label
  }) => {
    return (
      <>
        <IonItem className="mb-4">
          <IonLabel position="floating" color="primary">
            {label}
        </IonLabel>
        <Controller
          render={({ field: { onChange, value } }) => (
            <IonSelect
              value={value}
              onIonChange={onChange}
              interface="action-sheet"
              className="mt-2"
            >
                {opciones.map((opcion) => {
                   return (
                     <IonSelectOption value={opcion.value}
                       key={opcion.value}
                     >
                       {opcion.label}
                     </IonSelectOption>
                   );
                })}
            </IonSelect>
          )}
          control={control}
          name={name}
          defaultValue={defaultValue}
          rules={{
            required: "Este campo es obligatorio",
          }}
      />
    </IonItem>
      <ErrorMessage
        errors={errors}
        name={name}
        as={<div className="text-red-600 px-6" />}
      />
    </>
  );
};

export default Select;
Run Code Online (Sandbox Code Playgroud)

及其实现:

import React, { useEffect } from "react";
import Select from "components/Select/Select";
import { useForm } from "react-hook-form";
import Server from "server";

interface IData {
  age: String;
}

let defaultValues = {
  age: ""
}

const rulesEdad= {
  required: "Este campo es obligatorio",
}

const opcionesEdad = [
  {value: "1", label: "18-30"},
  {value: "2", label: "30-40"},
  {value: "3", label: "40-50"},
  {value: "4", label: "50+"}
]

const SelectExample: React.FC = () => {

const {
  control,
  handleSubmit,
  setValue,
  formState: { isSubmitting, isValid, errors },
} = useForm<IData>({
  defaultValues: defaultValues,
  mode: "onChange",
});

/**
 *
 * @param data
*/
const handlerButton = async (data: IData) => {
  console.log(data);
};

useEffect(() => {
 Server.getUserData()
  .then((response) => {
    setValue('age', response.age, { shouldValidate: true })
  }
}, [])

return (
  <form>
    <Select control={control} errors={errors}
      defaultValue={defaultValues.age} opciones={opcionesEdad}
      name={age} label={Edad} rules={rulesEdad}
    />
    <button
        onClick={handleSubmit(handlerSignInButton)}
        disable={!isValid || isSubmitting}
    >
      Guardar
    </button>
  </form>
Run Code Online (Sandbox Code Playgroud)