反应形式反应选择&是的。条件选择选项的问题&设置默认值

发布于 2025-02-10 21:08:10 字数 5383 浏览 3 评论 0原文

我无法弄清楚我是否在反应选择或反应钩形式方面遇到麻烦。基本上,我有一个称为“ Machinetype”的反应选择组件,可以将其设置为“单”或“多个”。设置为“单个”时,我需要使用平面列表来填充第二个名为“机器”的下拉列表。设置为“ Multi”时,我需要使用分组列表来填充第二个下拉列表。

在引擎盖下,这一切都使用setValue(我使用Watch()确认它已更改,您可以在我的示例中看到),但是在我的示例中,UI不会更改分组的React选择组件。

同样,由于某种原因(我使用yup& yupresolver,传递以使用useform),默认值不会加载分组的下拉列表,这确实在引擎盖下确实有效,但在UI中不显示。

我感觉我无法正确使用控制器组件。

自定义选择输入组件:

import * as React from "react";
import { Controller } from "react-hook-form";
import Select from "react-select";
    
type SelectInputProps = {
  control: any;
  register: any;
  options: any;
  name: string;
  errors: any;
  handleChange?: any;
  defaultValue: any;
} & React.ComponentPropsWithoutRef<"div">;

export default function SelectInput({
  control,
  register,
  options,
  name,
  errors,
  handleChange,
  defaultValue
}: SelectInputProps) {
  return (
    <div>
      <Controller
        control={control}
        defaultValue={defaultValue}
        name={name}
        render={({ field }) => (
          <Select
            {...field}
            id={name}
            instanceId={name}
            options={options}
            value={options.find((c) => c.value === field.value)}
            onChange={(selectedOption) => {
              field.onChange(selectedOption.value);
              if (typeof handleChange === "function") {
                handleChange(selectedOption.value);
              }
            }}
          />
        )}
      />
      <p>{errors[name]?.message}</p>
    </div>
  );
}

app.js

import SelectInput from "./SelectInput";
import "./styles.css";
import * as yup from "yup";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";

// #START----- Input options -------
const machineTypeOptions = [
  { label: "Multiple Machines", value: "multiple" },
  { label: "Single Machine", value: "single" }
];

const machineGroupOptions = [
  {
    label: "Mills",
    options: [
      { label: "All Mills", value: "allMills" },
      { label: "Cold Mills", value: "coldMills" },
      { label: "Finishing Hot Mills", value: "finishingHotMills" }
    ]
  },
  {
    label: "Furnaces",
    options: [
      { label: "All Furnaces", value: "allFurnaces" },
      { label: "HOM Furnaces", value: "homFurnaces" },
      { label: "Preheat Furnaces", value: "preHeatFurnaces" }
    ]
  }
];

const machineOptions = [
  { label: "CM1", value: "CM1" },
  { label: "CM2", value: "CM2" },
  { label: "CM3", value: "CM3" },
  { label: "HOMF1", value: "HOMF1" },
  { label: "PHF1", value: "PHF1" }
];
// #END----- Input options -------

//Schema
const schema = yup
  .object({
    machineType: yup
      .string()
      .oneOf(["single", "multiple"])
      .default("multiple")
      .required(),
    machine: yup.string().default("allMills").required()
  })
  .required();

export default function App() {
  //Form
  const {
    handleSubmit,
    control,
    register,
    watch,
    setValue,
    formState: { errors }
  } = useForm({
    defaultValues: schema.cast(),
    resolver: yupResolver(schema)
  });

  //Use for dynamically changing options in "machine"
  const watchMachineType = watch("machineType");

  //Watch form for changes
  const wholeForm = watch();
  console.log(wholeForm);

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <label>Machine Type</label>
      <SelectInput
        name="machineType"
        errors={errors}
        control={control}
        register={register}
        options={machineTypeOptions}
        handleChange={(value) => {
          if (value === "single") {
            setValue("machine", machineOptions[0].value);
          } else if (value === "multiple") {
            setValue("machine", machineGroupOptions[0].options[0].value);
          }
        }}
      />

      <label>Machine</label>

      {watchMachineType === "single" ? (
        <SelectInput
          name="machine"
          errors={errors}
          control={control}
          defaultValue={machineOptions[0]}
          options={machineOptions}
        />
      ) : (
        <SelectInput
          name="machine"
          errors={errors}
          control={control}
          defaultValue={machineGroupOptions[0].options[0]}
          options={machineGroupOptions}
        />
      )}

      {/* Another option below: conditonally alter the select options. 
      Neither seems to make a difference to the UI problem */}
      {/* <SelectInput
        name="machine"
        errors={errors}
        control={control}
        register={register}
        defaultValue={
          watchMachineType === "single"
            ? machineOptions[0].value
            : machineGroupOptions[0].options[0].value
        }
        options={
          watchMachineType === "single" ? machineOptions : machineGroupOptions
        }
      /> */}

      <button type="submit">Submit</button>
    </form>
  );
}

以下是问题的工作示例: https://codesandbox.io/s/weathered-cache-gache-g3b3ny?file=%2FSRC%2FAPP.JS

I can't figure out if I'm having trouble with react-select or react-hook-form. Basically I have a react-select component called 'machineType' which can be set to 'single' or 'multiple'. When set to 'single' I need to use a flat list to populate a second dropdown called 'machine'. When set to 'multi' I need to use a grouped list to populate the second dropdown.

Under the hood this all works using setValue (I have used a watch() to confirm that it has changed, you can see in my example) But the UI doesn't change for the grouped react-select component.

Also the default value doesn't load for the grouped dropdown for some reason (I am using yup & yupResolver, passed to useForm) Again this does work under the hood but doesn't show up in the UI.

I have a feeling I'm not using the Controller component correctly.

Custom Select Input Component:

import * as React from "react";
import { Controller } from "react-hook-form";
import Select from "react-select";
    
type SelectInputProps = {
  control: any;
  register: any;
  options: any;
  name: string;
  errors: any;
  handleChange?: any;
  defaultValue: any;
} & React.ComponentPropsWithoutRef<"div">;

export default function SelectInput({
  control,
  register,
  options,
  name,
  errors,
  handleChange,
  defaultValue
}: SelectInputProps) {
  return (
    <div>
      <Controller
        control={control}
        defaultValue={defaultValue}
        name={name}
        render={({ field }) => (
          <Select
            {...field}
            id={name}
            instanceId={name}
            options={options}
            value={options.find((c) => c.value === field.value)}
            onChange={(selectedOption) => {
              field.onChange(selectedOption.value);
              if (typeof handleChange === "function") {
                handleChange(selectedOption.value);
              }
            }}
          />
        )}
      />
      <p>{errors[name]?.message}</p>
    </div>
  );
}

App.js

import SelectInput from "./SelectInput";
import "./styles.css";
import * as yup from "yup";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";

// #START----- Input options -------
const machineTypeOptions = [
  { label: "Multiple Machines", value: "multiple" },
  { label: "Single Machine", value: "single" }
];

const machineGroupOptions = [
  {
    label: "Mills",
    options: [
      { label: "All Mills", value: "allMills" },
      { label: "Cold Mills", value: "coldMills" },
      { label: "Finishing Hot Mills", value: "finishingHotMills" }
    ]
  },
  {
    label: "Furnaces",
    options: [
      { label: "All Furnaces", value: "allFurnaces" },
      { label: "HOM Furnaces", value: "homFurnaces" },
      { label: "Preheat Furnaces", value: "preHeatFurnaces" }
    ]
  }
];

const machineOptions = [
  { label: "CM1", value: "CM1" },
  { label: "CM2", value: "CM2" },
  { label: "CM3", value: "CM3" },
  { label: "HOMF1", value: "HOMF1" },
  { label: "PHF1", value: "PHF1" }
];
// #END----- Input options -------

//Schema
const schema = yup
  .object({
    machineType: yup
      .string()
      .oneOf(["single", "multiple"])
      .default("multiple")
      .required(),
    machine: yup.string().default("allMills").required()
  })
  .required();

export default function App() {
  //Form
  const {
    handleSubmit,
    control,
    register,
    watch,
    setValue,
    formState: { errors }
  } = useForm({
    defaultValues: schema.cast(),
    resolver: yupResolver(schema)
  });

  //Use for dynamically changing options in "machine"
  const watchMachineType = watch("machineType");

  //Watch form for changes
  const wholeForm = watch();
  console.log(wholeForm);

  return (
    <form onSubmit={handleSubmit((data) => console.log(data))}>
      <label>Machine Type</label>
      <SelectInput
        name="machineType"
        errors={errors}
        control={control}
        register={register}
        options={machineTypeOptions}
        handleChange={(value) => {
          if (value === "single") {
            setValue("machine", machineOptions[0].value);
          } else if (value === "multiple") {
            setValue("machine", machineGroupOptions[0].options[0].value);
          }
        }}
      />

      <label>Machine</label>

      {watchMachineType === "single" ? (
        <SelectInput
          name="machine"
          errors={errors}
          control={control}
          defaultValue={machineOptions[0]}
          options={machineOptions}
        />
      ) : (
        <SelectInput
          name="machine"
          errors={errors}
          control={control}
          defaultValue={machineGroupOptions[0].options[0]}
          options={machineGroupOptions}
        />
      )}

      {/* Another option below: conditonally alter the select options. 
      Neither seems to make a difference to the UI problem */}
      {/* <SelectInput
        name="machine"
        errors={errors}
        control={control}
        register={register}
        defaultValue={
          watchMachineType === "single"
            ? machineOptions[0].value
            : machineGroupOptions[0].options[0].value
        }
        options={
          watchMachineType === "single" ? machineOptions : machineGroupOptions
        }
      /> */}

      <button type="submit">Submit</button>
    </form>
  );
}

Here's a working example of the problem: https://codesandbox.io/s/weathered-cache-g3b3ny?file=%2Fsrc%2FApp.js

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文