4

Following the Radio Group Example in the Formik docs and using Bootstrap 5 I've tried to create a boolean radio component that gets passed in a name and label. However, on render with the initialValues:

<Formik
  initialValues={{
    foo: false,
    bar: false,
  }}>

the no is selected because the initial value is set to false but whenever yes is chosen the radio will not fill in, component:

import React from 'react'
import PropTypes from 'prop-types'
import { Field } from 'formik'

const RadioBool = ({ name, label }) => {
  const yesId = `${name}-yes`
  const noId = `${name}-no`
  return (
    <>
      <p id={`${name}-group-label`}>{label}:</p>
      <div className="form-group mb-4" role="group" aria-labelledby={`${name}-group-label`}>
        <div className="form-check">
          <label htmlFor={yesId}>Yes</label>
          <Field id={yesId} className="form-check-input" type="radio" name={name} value={true} />
        </div>
        <div className="form-check">
          <label htmlFor={noId}>No</label>
          <Field id={noId} className="form-check-input" type="radio" name={name} value={false} />
        </div>
      </div>
    </>
  )
}

RadioBool.propTypes = {
  name: PropTypes.string.isRequired,
  label: PropTypes.string.isRequired,
}

export default RadioBool

but if checked is added to Yes, example:

<Field id={yesId} className="form-check-input" type="radio" name={name} value={true} checked />

the radio group works and I'm not sure why.

tests:

<RadioBool name="foo" label="Look at foo?" />
<RadioBool name="bar" label="Look at bar?" />

Research

Why does my boolean radio component not work in Formik unless checked is used on one <Field />?

DᴀʀᴛʜVᴀᴅᴇʀ
  • 7,681
  • 17
  • 73
  • 127
  • try removing `value` from field. In the example you mentioned, the `value` is used as string not true or false. Use `checked` property for initial value https://codesandbox.io/s/musing-heisenberg-kteomb – Usama Aug 01 '22 at 06:03

1 Answers1

3

The problem is described here Radio values must be strings, can't be numbers or booleans and as I see it's not solved 'from the box' yet.

In my TypeScript project I've created custom component. May it would be helpfull for you:

  import React, { FC } from 'react';

  type Props = {
    name: string
    value: boolean
    checked: boolean
    setValues: (values: React.SetStateAction<any>, shouldValidate?: boolean) => void;
  }
  
  const RadioButtonBooleanField: FC<Props> = ({name, value, checked, setValues}) => {
    return (
      <input type='radio' className="form-check-input" name={name} value={String(value)} checked={checked}
        onChange={(e: any) => {
          setValues((prevValues: any) => ({
            ...prevValues,
            [e.target.name]: e.target.value === "true"
            }))
          }
        } 
      />
    );
  };

It can be used like this inside Formik component:

{({ errors, touched, values, setValues }) => (
   <RadioButtonBooleanField name="IsExtendedView" value={false} checked={!values.IsExtendedView} setValues={setValues}/>
)}
Timothy
  • 584
  • 3
  • 14