Reputation: 2685
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.
Upvotes: 3
Views: 4392
Reputation: 807
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
Upvotes: 3