A
A
Alexander2021-07-06 16:21:34
React
Alexander, 2021-07-06 16:21:34

How to send data from custom list to react-hook-form?

Hello, please tell me how to correctly send the selected option through react-hook-form?
I use a Controller and render a custom list, but I don’t understand how to make the binding itself with react-hook-form, it seems like I added all the necessary properties {...field} for select, but after submitting the form I get an empty string (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>
      )}
    />
  )
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Igor Vasiliev, 2021-07-06
@Isolution666

Alexander, hello.
--
I so understood it is a question of this library. According to the React JS documentation , data is stored in value and default data is in defaultValue. If you use only value, React will complain that this data is not under its control. The afftarr of this plugin did not bother and used the same attributes as in React. It turns out the following.
import Select from 'react-select'

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

Here is what actually happens
const [select, setSelect] = useState([countryOptions[0], countryOptions[7]])

Here is the current state, where by default countryOptions shows the first and eighth entry.
What is data restructuring, I hope you know.
setSelect()will help mutate the state.
Receive and transmit what is in the state select.
Profit?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question