Formik Chakra-ui select not using value

Viewed 7640

I'm trying to submit a form with a drop down list. The issue is formik does not recognize the value from the options, not sure why or how to fix it.

const [value, setValue] = React.useState("");
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  setValue(event.target.value);
};
<Formik
    initialValues={{ ingredientId:"", }}
    onSubmit={async (values, { setErrors }) => {
        console.log(values);
    }}
>
    {({ isSubmitting }) => (
        <FormControl name="ingredientId" id="ingredientId">
            <FormLabel>Ingredient</FormLabel>
            <Select 
               name="ingredientId" 
               id="ingredientId" 
               onChange={handleChange} 
               value={value}
             >
                {ingredients!.map((ingredient: any) => {
                    return <option value={ingredient.id} id="ingredientId"> 
                        {ingredient.name}
                    </option>;
                })}
            </Select>
        </FormControl>
        ...
    )}
</Formik>

Though the ingredientId is still null after the submition, any idea?

2 Answers

It's funny, but even after 20+ years, this one still trips me up when I am in a hurry. Simply put, the selected option is not stored as the value of the select element.

To get the selected value, you'd need to do something like:

const { target } = event;

// note: 'select-multiple' for multi select
if (target.type === 'select-one') {
   const selectValue = target.selectedOptions[0].value;
}

https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/selectedOptions

You do not need to use value and handleChange. Formik will handle that. You can delete this lines

const [value, setValue] = React.useState("");
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
  setValue(event.target.value);
};

Try to use <Field> from formik and {field.onChange} or {form.handleChange}. Example:

    <Formik
      initialValues={{ ingredientId: '' }}
      onSubmit={(values, actions) => {
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
          actions.setSubmitting(false);
        }, 1000);
      }}>
      {(props) => (
        <Form>
          <Field>
            {({ field, form }: FieldProps) => (
              <FormControl name="ingredientId" id="ingredientId">
                <FormLabel>Ingredient</FormLabel>
                <Select
                  name="ingredientId"
                  id="ingredientId"
                  onChange={field.onChange} // or {form.handleChange}
                  value={value}>
                  {ingredients!.map((ingredient: any) => (
                    <option
                      key={ingredient.id}
                      value={ingredient.id}
                      id="ingredientId">
                      {ingredient.name}
                    </option>
                  ))}
                </Select>
              </FormControl>
            )}
          </Field>
          <Button isLoading={props.isSubmitting} type="submit">
            Submit
          </Button>
        </Form>
      )}
    </Formik>

See https://formik.org/docs/api/formik

Related