首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React钩子形式的“忽略”选择

React钩子形式的“忽略”选择
EN

Stack Overflow用户
提问于 2021-10-10 18:31:55
回答 1查看 1.2K关注 0票数 1

我有一个有很多字段的表格。以下只是其中的一部分:

代码语言:javascript
复制
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时,我得到以下内容:

代码语言:javascript
复制
{emailRequired: "test@test.com", nameRequired: "Test", surnameRequired: "Test", streetRequired: "xxxx", numberRequired: "123", …}

基本上我所有的选择都被忽略了。

我试图注册select字段,但值未定义:

代码语言:javascript
复制
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组件:

代码语言:javascript
复制
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>
  );
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-10 20:32:30

组件Listbox (是一个外部控制的组件)不是本地的HTML。在这种情况下,要处理这个组件,您应该使用包装器组件:Controller,它允许您自由地使用自定义寄存器。

这来自表单:

React表单包含不受控制的组件和本地的HTML输入,但是,很难避免使用外部控制的组件,如React-Select、AntD和Material。为了简化这一点,我们提供了一个包装组件:控制器,以简化集成过程,同时仍然允许您自由使用自定义寄存器。

代码语言:javascript
复制
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>
      )}
    />
  );
};

下面是一个关于如何将ListboxReact Hook Formhttps://codesandbox.io/s/react-hook-form-v7-controller-forked-6t7qg?file=/src/MyListbox.js:173-180结合使用的简单演示

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69517931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档