反应形式反应选择&是的。条件选择选项的问题&设置默认值
我无法弄清楚我是否在反应选择或反应钩形式方面遇到麻烦。基本上,我有一个称为“ 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论