React Hook Form 将复选框设置为选中状态

React Hook Form set checkbox to checked state

我正在尝试React-Hook-form

复选框的简单代码如下:

import React from 'react'
import { useForm } from 'react-hook-form'

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm()
  const onSubmit = (data: any) => console.log(data)
  console.log(errors)

  return (
    <div className='mx-auto justify-center p-32 flex'>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div className='p-2'>
          <label htmlFor=''>January</label>
          <input
            type='checkbox'
            placeholder='January'
            {...register('January', {})}
            className='mx-3'
            checked
          />
        </div>
        <div className='p-2'>
          <label htmlFor=''>February</label>
          <input
            type='checkbox'
            placeholder='February'
            {...register('February', {})}
            className='mx-3'
          />
        </div>
        <input type='submit' />
      </form>
    </div>
  )
}

我可以正确提交表单,但我希望一月复选框以复选框的形式开始,但是当我按照代码所示输入 'checked' 时,我无法 'uncheck' 它.

我似乎遗漏了什么,如有任何帮助,我们将不胜感激。

传递 checked 的问题是它从 useForm 中夺走了管理复选框的控制权。

想象函数 register() returns { checked: true/false, onChange: changeHandler }。因此,如果我们在哪里查看属性,则会产生以下内容。

<input
  type='checkbox'
  placeholder='January'
  {...register('January', {})}
  className='mx-3'
  checked
/>

<input
  type='checkbox'
  placeholder='January'
  {...{
    checked: true/false,
    onChange: changeHandler,
  }}
  className='mx-3'
  checked
/>

<input
  type='checkbox'
  placeholder='January'
  checked={true/false}
  onChange={changeHandler}
  className='mx-3'
  checked
/>

由于 checked 出现了两次,后者将覆盖前者。在这种情况下,您的 checked 是最后一个,因此它会覆盖 useForm.

管理的值

register() 调用之前传递它也无济于事,因为您的默认值将被 useForm 管理的值覆盖,因此永远不会被使用。


现在我已经弄清楚了为什么会出现这个问题,让我们继续解决方案。

useForm 允许您在最初调用挂钩时传递默认值。

const {
  register,
  handleSubmit,
  formState: { errors },
} = useForm({ defaultValues: { January: true } });

// ...

<input
  type='checkbox'
  {...register("January")}
  className='mx-3'
/>

或者,您也可以使用 "months",而不是给每个复选框单独命名。如果有多个复选框使用相同的名称,结果将不是 true/false,而是一个包含值的数组。

const {
  register,
  handleSubmit,
  formState: { errors },
} = useForm({
  defaultValues: { months: ["January"] }
  //               only January ^ is checked by default
});

//...

<input
  type='checkbox'
  value='January'
  {...register("months")}
  className='mx-3'
/>
<input
  type='checkbox'
  value='February'
  {...register("months")}
  className='mx-3'
/>

基于@3limin4tOr

的完整工作代码
import React, { useState } from 'react'
import { useForm } from 'react-hook-form'

export default function App() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm({
    defaultValues: { months: ['January'] },
  })

  const onSubmit = (data: any) => console.log(data)
  console.log(errors)

  return (
    <div className='mx-auto justify-center p-32 flex'>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div className='p-2'>
          <label htmlFor=''>January</label>
          <input
            type='checkbox'
            value='January'
            placeholder='January'
            {...register('months')}
            className='mx-3'
          />
        </div>
        <div className='p-2'>
          <label htmlFor=''>February</label>
          <input
            type='checkbox'
            value='February'
            placeholder='February'
            {...register('months')}
            className='mx-3'
          />
        </div>
        <input type='submit' />
      </form>
    </div>
  )
}