3
votes

I am trying to use React, Formik, react-select and Firebase (cloud firestore) to build a form in react.

It all works fine when I only use react-select once. There is only one state to update. When I try to use more than one drop down, I get an error that says:

Unhandled Rejection (FirebaseError): Function DocumentReference.set() called with invalid data. Unsupported field value: undefined (found in field fieldOfResearch)

I don't know what this error message means. I've employed multiple code mentors and devs from upwork/codementor etc - and now the code is a shambles and untraceable back to the Formik documents - however, it works when I use react-select once. I think the problem might be something to do with how I name the fields to differentiate the state updates.

I have:

const initialValues = {
  fieldOfResearch: null,
  disclosureStatus: null,
}

Both of these are react-select fields in my form.

Then I have:

class ProjectForm extends React.Component {
  state = {
    selectedValue1: null,
    selectedValue2: null,

  };

  handleSelectChange1 = selectedValue1 => {
    this.setState({ selectedValue1 });
  };

  handleSelectChange2 = selectedValue2 => {
    this.setState({ selectedValue2 });
  };

SelectedValue1 is what I'm using for fieldOfResearch and SelectedValue2 is for disclosureStatus.

handleSubmit = (formState, { resetForm }) => {
    console.log("SUCCESS!! :-)\n\n", formState);
    fsDB
      .collection("project")
      .add(formState)
      .then(docRef => {
        console.log("docRef>>>", docRef);
        this.setState({ selectedValue1: null });
        this.setState({ selectedValue2: null });

        resetForm(initialValues);
      })
      .catch(error => {
        console.error("Error adding document: ", error);
      });
  };

Then in my render method, I have:

render() {
    return (
      <Formik
        initialValues={initialValues}


onSubmit={this.handleSubmit}
        render={({ errors, status, touched, setFieldTouched, handleSubmit, values }) => {
          let fieldOfResearch;
          const handleChange1 = optionsObject => {
            fieldOfResearch = optionsObject;
            return (values.fieldOfResearch = optionsObject.value);
          };
          let disclosureStatus;
          const handleChange2 = confidentialityObject => {
            disclosureStatus = confidentialityObject;
            return (values.disclosureStatus = confidentialityObject.value);
          };

The form group elements are:

<div className="form-group">
                                <label htmlFor="fieldOfResearch">
                                Select your field(s) of research
                                </label>

                                <Select
                                key={`my_unique_select_key__${fieldOfResearch}`}
                                name="fieldOfResearch"
                                isMulti={true}
                                className={
                                    "react-select-container" +
                                    (errors.fieldOfResearch && touched.fieldOfResearch ? " is-invalid" : "")
                                }
                                classNamePrefix="react-select"
                                value={this.state.selectedValue1}
                                onChange={e => {
                                    handleChange1(e);
                                    this.handleSelectChange1(e);
                                }}
                                onBlur={setFieldTouched}
                                options={options}
                                />
                                {errors.fieldOfResearch && touched.fieldOfResearch && 
                                <ErrorMessage
                                name="fieldOfResearch"
                                component="div"
                                className="invalid-feedback d-block"
                                />}
                                </div>

I was trying to use Yup for validation, with the following:

fieldOfResearch: Yup.array().required("What is your field of research?"),

From the text of the error message, I think the part it doesn't like is the handle submit method:

this.setState({ selectedValue1: null });

Does anyone know how to handle multiple fields that have a state in them with react-select, formik, firebase and react?

I took this whole form apart and started again. I think part of the problem may have something to do with the react-select isMulti option - which allows a field to have multiple values.

From the react-select documents, I think it is supposed to be used on the field as follows:

                      isMulti={true}

When I try that, the form renders in local and allows multiple values to be selected, but saves them all as undefined. The error copied above throws when it tries to post to the database.

So - does anyone know how to use react-select with multiple input values on a select menu?

I have seen this question and the answer explaining how to use Formik with react-select, but I can't make any sense of it, or see how it could be integrated with the form structure that I am using.

I have also seen this Code Sandbox which shows a way this can be done in a language other than jsx. I can't figure out how to incorporate this approach into my form structure.

1
Can you share a code sandbox link? Also, if you are storing values in state, I cant see any real advantage of using Formik.Dani Vijay
What do you mean @DaniVijay about storing values in state. What other option is there?Mel
it seems like you are using formState to submit values, so you are already utilising the internal state of Formik. Why don't you use values.fieldOfResearch for setting value in the field(instead of value={this.state.selectedValue1}). Am I missing something?Dani Vijay
I don't know about React-Select and Formik, but... In your handleSubmit function, you're accepting a formState object from the form and trying to add it to your Firestore collection. According to the Firestore error, formState contains a 'fieldOfResearch' property which is set to undefined. Firestore will accept null values, but not undefined. I'd guess there's something in your onChange handlers mucking up the fieldOfResearch value.MurrayR

1 Answers

3
votes

Here is a codesandbox that I believe solves your issues. It doesn't include the add to firestore method in the handleSubmit function.

I made one field a multi-select and the other a plain select as examples.

https://codesandbox.io/s/formik-and-reactselect-example-i67l6