Search code examples
reactjsmaterial-uiformikformik-material-ui

How to set MenuSelect value to a boolean in a Formik form?


I'm working in a Formik form and I have a very simple material UI Select dropdown list:

<FormControlLabel 
     control={
        (
          <Field component={Select} type="checkbox" name="isFoundationalSupport">
               <MenuItem value="yes">Yes</MenuItem>
               <MenuItem value="no">No</MenuItem>
               <MenuItem value="null">Unknown</MenuItem>
           </Field>
         )
      }
      label="Foundational support"
      labelPlacement="top"
 />

For the three menu items, I would like the values to be true, false, or null but those are not acceptable values for the value field in MenuItem. Is my only route to use component state? I was hoping to keep it simple and stick with Formik state and values but not sure that's possible in this case.


Solution

  • Because MenuItem's prop value only accepts string or number, you'll have to convert it in an onChange handler.

    You don't need any extra state to perform this, you can simply use formik's function setFieldValue().

    // define all the options
    const selectOptions = [
      { id: true, text: "Yes" },
      { id: false, text: "No" },
      { id: null, text: "Unknown" }
    ];
    
    // and in the component
    <FormControlLabel
      control={
        <Field
          component={Select}
          placeholder="Select One"
          type="checkbox"
          value={
            selectOptions.find(
              ({ id }) => id === values.isFoundationalSupport
            ).text
          }
          name="isFoundationalSupport"
          onChange={(e) => {
            if (e.target.value) {
              const { id } = selectOptions.find(
                ({ text }) => text === e.target.value
              );
              setFieldValue("isFoundationalSupport", id);
            }
          }}
        >
          {selectOptions.map(({ text }) => (
            <MenuItem key={text} value={text}>
              {text}
            </MenuItem>
          ))}
        </Field>
      }
      label="Foundational support"
      labelPlacement="top"
    />
           
    

    Working Example