axrising
@axrising

Как отправить даные с кастомного списка в react-hook-form?

Здравствуйте, подскажите пожалуйста как правильно отправлять выбраный option через react-hook-form?
Я использую Controller и делаю render кастомного списка, но не понимаю как сделать саму связку с react-hook-form, вроде как добавил все нужные свойства {...field} для select, но после отправки формы - получаю пустую строку (country: " ")

const methods = useForm<IFormInputs>({
    resolver: yupResolver(RegisterSchema),
  })

  const onSubmit = (data: IFormInputs) => {
    console.log(data)
  }

 <FormProvider {...methods}>
        <Form onSubmit={methods.handleSubmit(onSubmit)}>
          <Select
          options={[
              { value: 'canada', label: 'Canada' },
              { value: 'france', label: 'France' },
              { value: 'spain', label: 'Spain' },
            ]}
            name='country'
          />
        </Form>
      </FormProvider>


export const Select: React.FC<SelectProps> = ({ name, options }) => {
  const {
    control,
    formState: { errors },
  } = useFormContext()

  const [isOpen, setOpen] = React.useState<boolean>(false)
  const [selected, setSelected] = React.useState()
  console.log(selected)

  return (
    <Controller
      control={control}
      name={name}
      render={({ field }) => (
        <Container isOpen={isOpen} isError={!!errors[name]?.message}>
          <select {...field} id={name} className='html-select'>
            {options.map((item: any) => (
              <option key={`${item.value}-option`} value={item.value}>
                {item.label}
              </option>
            ))}
          </select>
          <div
            onClick={() => {
              setOpen((prev) => !prev)
            }}
            className='custom-select-wrapper'
          >
            <div className={`custom-select ${isOpen && 'open'}`}>
              <div className='custom-select__trigger'>
                <span>{options.find((item: any) => item.value === selected)?.label || 'Select country'}</span>
                <div className='arrow'></div>
              </div>
              <div className='custom-options'>
                {options.map((item: any) => (
                  <div
                    key={`${item.value}-option2`}
                    onClick={() => {
                      setSelected(item.value)
                    }}
                    className='option-container'
                  >
                    <span className={`custom-option ${selected === item.value && 'selected'} `} data-value={item.value}>
                      {item.label}
                    </span>
                  </div>
                ))}
              </div>
            </div>
          </div>
          {errors && <Error>{errors[name]?.message}</Error>}
        </Container>
      )}
    />
  )
}
  • Вопрос задан
  • 1219 просмотров
Пригласить эксперта
Ответы на вопрос 1
Isolution666
@Isolution666
Full-Stack Developer
Александр, здравствуйте.
--
Я так понял речь идёт об этой библиотеке.
import Select from 'react-select'

Согласно документации по React JS, данные заносятся в value, а данные по умолчанию в defaultValue. Если использовать только value, React будет ругаться на то что эти данные не под его контролем.
Аффтарр этого плагина не стал заморачиваться и использовал те же аттрибуты что и в React.
Получается следующее.

<Select
  isMulti // разрешить множественный выбор
  placeholder="Choose country" // текст в поле если пусто
  closeMenuOnSelect={true} // разрешать кнопку удаления тегов внутри инпут
  value={countryOptions.find(obj => obj.value === select)} // тут выбранные страны
  defaultValue={select} // тут из стейта по умолчанию
  name="country"  //  имя селекта
  onChange={handleChange} // сюда можно вставить функцию которая будет следить за событиями
  options={countryOptions} // массив данных, откуда выбираются страны
  styles={countryStyles} // стилистика, цвета и размеры
/>


Вот собственно и получается
const [select, setSelect] = useState([countryOptions[0], countryOptions[7]])

Вот текущий стейт, в котором по умолчанию countryOptions показывает первую и восьмую запись.
Что такое реструктуризация данных, надеюсь, вы знаете.
setSelect() поможет мутировать стейт.
Получить и передать, то что в стейте select.

Профит ?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы