Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Hook Forms + Material UI Checkboxes

I am having an error when submiting a form build using React Hook Form and material-ui checkboxes components. The number of checkboxes are build from a list from my api:

        <Grid item xs={12}>
          <FormControl
            required
            error={errors.project?.stack ? true : false}
            component='fieldset'>
            <FormLabel component='legend'>Tech Stack</FormLabel>
            <FormGroup>
              <Grid container spacing={1}>
                {techs.map((option, i) => (
                  <Grid item xs={4} key={i}>
                    <FormControlLabel
                      control={
                        <Checkbox
                          id={`stack${i}`}
                          name='project.stack'
                          value={option.id}
                          inputRef={register({required: 'Select project Tech Stack'})}
                        />
                      }
                      label={option.name}
                    />
                  </Grid>
                ))}
              </Grid>
            </FormGroup>
            <FormHelperText>{errors.project?.stack}</FormHelperText>
          </FormControl>
        </Grid>

When the form is submited I got the following error ( several times , 1 for each checkbox rendered ) :

Uncaught (in promise) Error: Objects are not valid as a React child (found: object with keys {type, message, ref}). If you meant to render a collection of children, use an array instead.

I don't understand this error. The message apparently says it is a rendering issue, but the component renders fine. The problems happens on submit. Any advices ?

Thank you

like image 532
Felipe V Avatar asked Jun 09 '20 21:06

Felipe V


People also ask

How to multiselect checkbox with react-Hook-form and material-UI?

If someone struggle to achieve multiselect checkbox with React material-ui and react-hook-form you can check my codesandbox example Also, there is a code example provided by react-hook-form in their documentation under useController chapter (don't forget to switch to the checkboxes tab). Material UI + React Hook Form + Yup .

What is the difference between React Native and material UI checkbox?

The native checkbox input is hidden and instead a checkbox SVG icon (or a custom icon of your choice) is used. This is a fairly simple component. Using the Material UI Checkbox is essentially the same as native React inputs.

What is react Hook form?

Also, I am a blogger in my free time and love to write about various technical topics. React Hook Form is one of the most popular libraries for handling form inputs in the React ecosystem. Getting it to work properly can be tricky if you’re using a component library such as Material UI.

Do I need a date picker in react Hook form?

This will inject the date picker functionality for us. Remember, this is not a requirement for React Hook Form; it’s required by Material UI. So if you’re using any other design library, such as Ant Design or Semantic UI, you don’t need to worry about it. If you want to use a simple checkbox that works like a switch, then it’s easy to use.


5 Answers

If someone struggle to achieve multiselect checkbox with React material-ui and react-hook-form you can check my codesandbox example

Also, there is a code example provided by react-hook-form in their documentation under useController chapter (don't forget to switch to the checkboxes tab).

enter image description here

like image 78
Roman Mahotskyi Avatar answered Oct 22 '22 07:10

Roman Mahotskyi


Material UI + React Hook Form + Yup . Example page: https://moiseshp.github.io/landing-forms/

  • Without extra dependences
  • Show and hide error messages
// import { yupResolver } from '@hookform/resolvers/yup'
// import * as yup from 'yup'

const allTopics = [
  'React JS',
  'Vue JS',
  'Angular'
]

const defaultValues = {
  topics: []
}

const validationScheme = yup.object({
  topics: yup.array().min(1),
})

const MyForm = () => {
  const resolver = yupResolver(validationScheme)

  const {
    control,
    formState: { errors },
    handleSubmit
  } = useForm({
    mode: 'onChange',
    defaultValues,
    resolver
  })

  const customSubmit = (data) => alert(JSON.stringify(data))

  return (
    <form onSubmit={handleSubmit(customSubmit)}>
      <FormControl component="fieldset" error={!!errors?.topics}>
        <FormLabel component="legend">Topics</FormLabel>
        <FormGroup row>
          <Controller
            name="topics"
            control={control}
            render={({ field }) => (
              allTopics.map(item => (
                <FormControlLabel
                  {...field}
                  key={item}
                  label={item}
                  control={(
                    <Checkbox
                      onChange={() => {
                        if (!field.value.includes(item)) {
                          field.onChange([...field.value, item])
                          return
                        }
                        const newTopics = field.value.filter(topic => topic !== item)
                        field.onChange(newTopics)
                      }}
                    />
                  )}
                />
              ))
            )}
          />
        </FormGroup>
        <FormHelperText>{errors?.topics?.message}</FormHelperText>
      </FormControl>
    </form>
  )
}

export default MyForm
like image 29
Moises Huaringa Avatar answered Oct 22 '22 05:10

Moises Huaringa


UPDATE: if you are using RHF >= 7, you should use props.field to call props.field.value and props.field.onChange.


You can use the default Checkbox Controller:

<FormControlLabel
    control={
      <Controller
        name={name}
        control={control}
        render={({ field: props }) => (
          <Checkbox
            {...props}
            checked={props.value}
            onChange={(e) => props.onChange(e.target.checked)}
          />
        )}
      />
    }
    label={label}
  />

I used the controller example from RHF but had to add checked={props.value}: https://github.com/react-hook-form/react-hook-form/blob/master/app/src/controller.tsx

like image 42
Juan García Avatar answered Oct 22 '22 05:10

Juan García


I managed to make it work without using Controller. The props should be inside the FormControlLabel and not inside Checkbox

                <Grid item xs={4} key={i}>
                    <FormControlLabel
                      value={option.id}
                      control={<Checkbox />}
                      label={option.name}
                      name={`techStack[${option.id}]`}
                      inputRef={register}
                    />
                  </Grid>
                ))}
like image 38
Felipe V Avatar answered Oct 22 '22 05:10

Felipe V


Here is the simplest way to do it using Controller

<Box>
<Controller
  control={control}
  name={`${dimension.id}-${dimension.name}`}
  defaultValue={false}
  render={({ field: { onChange, value } }) => (
    <FormControlLabel
      control={
        <Checkbox checked={value} onChange={onChange} />
      }
    />
  )}
/>
</Box>
like image 1
DINA TAKLIT Avatar answered Oct 22 '22 07:10

DINA TAKLIT