我有一个有很多字段的表格。以下只是其中的一部分:
return (
<>
<FormProvider {...methods} >
<div className="mt-12">
<form onSubmit={handleSubmit(onSubmit)} action="#" method="POST" >
<Email/>
<Personal/>
<h2 className='font-semibold text-xl'>Geburtsdaten</h2>
<p className='mb-5 text-gray-400 text-sm'>Du musst mindestens 18 Jahre alt sein, um online einen Vertrag abzuschließen.</p>
<div className="sm:col-span-2 grid grid-cols-3 gap-4 mb-5">
<div className="mt-1">
<SelectBirthYear
years={years}
value={selectedYear}
onChange={setSelectedYear}/>
</div>
<div className="mt-1">
< SelectBirthMonth
startYear={startYear}
selectedYear={selectedYear}
months={months}
value={selectedMonth}
reducedMonths={reducedMonths}
onChange={monthSelect}/>
</div>SelectBirthYear和SelectBirthMonth是选择。因此,当提交I console.log formData时,我得到以下内容:
{emailRequired: "test@test.com", nameRequired: "Test", surnameRequired: "Test", streetRequired: "xxxx", numberRequired: "123", …}基本上我所有的选择都被忽略了。
我试图注册select字段,但值未定义:
export const SelectBirthYear = ({ years, value, onChange }) => {
const {register} = useFormContext();
return (
<Listbox value={value} onChange={onChange} >
{({ open }) => (
<>
<Listbox.Label className="block text-sm font-medium text-gray-700 xs:text-xs">Geburtsjahr</Listbox.Label>
<div className="mt-1 relative">
<Listbox.Button className="bg-white relative w-full border border-gray-300 rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default focus:outline-none focus:ring-1 focus:ring-yellow-500 focus:border-yellow-500 sm:text-sm">
<span className="block truncate">{value.name}</span>
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<SelectorIcon className="h-5 w-5 text-gray-400" aria-hidden="true" />
</span>
</Listbox.Button>
<Transition
show={open}
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options
static
{...register("birthYear")}
className="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm"
>
{years.map((year, index) => (
<ListboxOption
key={index}
value={year}
date={year.name}
>
</ListboxOption>
))}
</Listbox.Options>
</Transition>
</div>
</>
)}
</Listbox>
)
}emailRequired:"test@test.com",nameRequired:“测试”,surnameRequired:“测试”,birthYear:未定义
我做错了什么?
我的Listbox.Option组件:
import { CheckIcon } from '@heroicons/react/solid';
import { Listbox } from '@headlessui/react';
function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}
export const ListboxOption = ({ value, date }) => {
return (
<Listbox.Option
className={({ active }) => classNames( active ? 'text-white bg-yellow-500' : 'text-gray-600', 'cursor-default select-none relative py-2 pl-3 pr-9')}
value={value}
>
{({ selected, active }) => (
<>
<span className={classNames(selected ? 'font-semibold' : 'font-normal', 'block truncate')}> {date} </span>
{selected ? (
<span className={classNames(active ? 'text-white' : 'text-yellow-500','absolute inset-y-0 right-0 flex items-center pr-4' )}>
<CheckIcon className="h-5 w-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
);
}发布于 2021-10-10 20:32:30
组件Listbox (是一个外部控制的组件)不是本地的HTML。在这种情况下,要处理这个组件,您应该使用包装器组件:Controller,它允许您自由地使用自定义寄存器。
这来自表单:
React表单包含不受控制的组件和本地的HTML输入,但是,很难避免使用外部控制的组件,如React-Select、AntD和Material。为了简化这一点,我们提供了一个包装组件:控制器,以简化集成过程,同时仍然允许您自由使用自定义寄存器。
export const SelectBirthYear = ({ years }) => {
const { control } = useFormContext();
return (
<Controller // <=== You should use this wrapper
name="birthYear"
control={control}
render={({ field }) => (
<Listbox value={field.value} onChange={field.onChange}>
{({ open }) => (
<>
<Listbox.Label className="block text-sm font-medium text-gray-700 xs:text-xs">
Geburtsjahr
</Listbox.Label>
<div className="mt-1 relative">
<Listbox.Button className="bg-white relative w-full border border-gray-300 rounded-md shadow-sm pl-3 pr-10 py-2 text-left cursor-default focus:outline-none focus:ring-1 focus:ring-yellow-500 focus:border-yellow-500 sm:text-sm">
<span className="block truncate">{field.value.name}</span>
<span className="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<SelectorIcon
className="h-5 w-5 text-gray-400"
aria-hidden="true"
/>
</span>
</Listbox.Button>
<Transition
show={open}
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options
static
className="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-md py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm"
>
{years.map((year, index) => (
<ListboxOption
key={index}
value={year}
date={year.name}
></ListboxOption>
))}
</Listbox.Options>
</Transition>
</div>
</>
)}
</Listbox>
)}
/>
);
};下面是一个关于如何将Listbox与React Hook Form:https://codesandbox.io/s/react-hook-form-v7-controller-forked-6t7qg?file=/src/MyListbox.js:173-180结合使用的简单演示
https://stackoverflow.com/questions/69517931
复制相似问题