dumdum3000
dumdum3000

Reputation: 335

How to use react hook form's Controller with radio buttons

The Problem:

What I'm trying to do:

Examples:

Code Sandbox

  1. Use WrapperRadio in RegistrationForm
    <form onSubmit={onSubmit}>
      <WrapperRadio
        control={control}
        name="radioSelection"
        label="This is a label"
      />
    ...
    </form>
  1. Using Controller in WrapperRadio

    return (
        <div>
          <Controller
            control={control}
            name={name}
            render={({ field }) => <RadioButton {...field} label={label} />}
          />
        </div>
      );
  1. Atomic RadioButton component
    return (
        <fieldset className="max-w-sm">
          <input
            ref={ref}
            id={name}
            name={name}
            type="radio"
            aria-label={label}
            {...props}
          />
          <label htmlFor={name} className="block text-sm font-medium text-gray-700">
            {label}
          </label>
        </fieldset>
      );

Upvotes: 3

Views: 22314

Answers (3)

Abhay Pandey
Abhay Pandey

Reputation: 11

      <Controller
        control={control}
        rules={{
          required: true,
        }}
        render={({ field: { onChange, value } }) => (

          <RadioButton.Group onValueChange={onChange} value={value}>
            

              <View >
                <Text >
                  Gender
                </Text>
              </View>

              <View >
                <RadioButton
                  value="Male"
                  color="#FF6B01"
                />
                <Text >
                  Male
                </Text>
              </View>

              <View >
                <RadioButton
                  value="Female"
                  color="#FF6B01"
                />
                <Text style=>
                  Female
                </Text>
              </View>
            </View>
          </RadioButton.Group>
        )}
        name="gender"
      />
    </View>

Upvotes: 0

dumdum3000
dumdum3000

Reputation: 335

Here's another approach that allows the input's value to be read as a string but has the downside of putting the onChange in the atomic RadioButton component (instead of keeping it stateless).

  1. WrapperRadio in RegistrationForm

options is an array of the desired radio button answer options which makes the WrapperRadio reusable.

    <WrapperRadioGroup
      name="radioSelection"
      label="This is a radio group label"
      control={control}
      options={ ["chocolate", "vanilla" ] }
      value="ice-cream"
     >
  1. Controller in WrapperRadio

Map through options to create a new radio button label for each one and pass onChange to the atomic RadioButton component.

return (
    <>
      {/* {label} */}
      <Controller
        control={control}
        name={name}
        defaultValue={props.value}
        render={({ field: {onChange, ...props} }) => 
          options.map((option, index) => (
    
           <RadioButton
             key={index}
             {...props} 
             onChange={onChange}
             value={option}  
             label={label} 
          />
          ))
        }
      />
    </>  

  )
  1. Atomic RadioButton component

onChange updates rhf's form state with the correct value


return (
      <>
        <input 
          ref={ref} 
          name={name} 
          type="radio" 
          value={value} 
          aria-label={label}
          onChange={ () => props.onChange(props.value) }
          {...props} />
        <label htmlFor={name}>Radio answer option</label>
      </>
    )
  }

Upvotes: 2

justin
justin

Reputation: 345

  1. Use WrapperRadio in RegistrationForm - you should pass in a default value.

       <form onSubmit={onSubmit}>
          <WrapperRadio
            control={control}
            name="radioSelection"
            label="This is a label"
            value={true}
          />
        </form>
    
  2. Using Controller in WrapperRadio

            return (
              <div>
                 <Controller
                  control={control}
                  name={name}
                  render={({ field: {onChange, ...props} }) => 
                  <RadioButton
                  onChange={e => onChange(e.target.checked)}
                  {...props} label={label} />}
               />
              </div>
    

Upvotes: 3

Related Questions