Is it possible to get a set of checkboxes in react-hook-form to bind to a single array?

Viewed 1500

I am using react-hook-form with material-ui checkboxes. The following code works fine; however, each checkbox gets bound to its own field. In partial, when I hit submit, the output is something like this: {option1: true, option2: undefined, option3: true}

What I am hoping for is to get the output from all three checkboxes to bind into a single array, i.e. for the output to be something like this: {checkboxFieldName: [option1, option3]}.

I know that when using Formik, this is possible when the FormControlLabels of all checkboxes have the same names. So, just wondering if something similar is possible with react-hook-form.

Thank you in advance.

const options = [
  { key: 'option1', label: 'Option 1', val: 'option1' },
  { key: 'option2', label: 'Option 2', val: 'option2' },
  { key: 'option3', label: 'Option 3', val: 'option3' },
]

function App() {
  const { handleSubmit, control } = useForm();
  const onSubmit = data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <FormControl>
        <FormLabel>Check all suitable options</FormLabel>
        <FormGroup>
          {options.map((option) => (
            <FormControlLabel
              key={option.key}
              name='checkboxFieldName'
              value={option.val}
              control={
                <Controller
                  control={control}
                  name={option.key}
                  render={({ field: { onChange, value }}) => (  
                    <Checkbox
                      checked={value}
                      onChange={e => onChange(e.target.checked)}
                    />)}
                />}
              label={option.label}
            />)
          )}
        </FormGroup>
      </FormControl>
      <Button type="submit">Save</Button>
    </form>
  );
}
1 Answers

I tried to do the same thing with Material UI but I ended up with more problems. Basically, you need to store selected checkboxes somewhere else (within an array) and set them to react-hook-form's state by using setValue function: https://react-hook-form.com/api/useform/setvalue/ Example: https://blog.logrocket.com/using-material-ui-with-react-hook-form/

If you don't want to do it manually, I would suggest using react-spectrum. It has a CheckboxGroup component and it stores all the selected values in an array: https://react-spectrum.adobe.com/react-spectrum/CheckboxGroup.html

Another solution is that you don't try to convert material-ui's object (checkboxFieldName: {option1: true, option2: undefined, option3: true}) into an array ({checkboxFieldName: [option1, option3]}) before submitting. Once you submit your form, you can convert your checkboxFieldName object into an array before passing the data to an API. Such as:

let checkboxFieldName = {option1: true, option2: undefined, option3: true}

let redefinedCheckboxFieldName = []
Object.entries(checkboxFieldName).forEach(([key, value]) => {
   if(value){
       redefinedCheckboxFieldName.push(key)
   }
})
Related