I'm working with a react form validation using Yup
along with Formik
.
There is a react-select
element in the form which needs to be validated as well. For validation i'm making use of validationSchema
of Formik
to validate form on value change.
I need only value of the select field as a string so cant take the complete object (key-value).
The select field is working fine how ever the validation error message is not cleared.
The question is how can I validate the select field with existing approach?
Below is the minimal code sample.
import ReactDOM from "react-dom";
import React, { useState } from "react";
import { Grid, TextField, Button } from "@material-ui/core";
import { Formik } from "formik";
import * as Yup from "yup";
import Select from "react-select";
import "./styles.css";
function App() {
const [selectedYear, setSelectedYear] = useState("");
const testSchema = Yup.object().shape({
name: Yup.string().required("Enter Name"),
year: Yup.string().required("Select Year")
});
const initialValues = {
name: "",
year: ""
};
const handleYearChange = (selectedYear, values) => {
values.year = selectedYear.value;
console.log(selectedYear);
setSelectedYear(selectedYear);
};
const yearOptions = [
{ value: "1960", label: "1960" },
{ value: "1961", label: "1961" },
{ value: "1962", label: "1962" },
{ value: "1963", label: "1963" },
{ value: "1964", label: "1964" },
{ value: "1965", label: "1965" }
];
return (
<Formik validationSchema={testSchema} initialValues={initialValues}>
{({
handleChange,
handleBlur,
values,
errors,
touched,
handleSubmit,
setFieldTouched
}) => {
return (
<>
<Grid container spacing={2}>
<Grid item md={12} xs={12}>
<TextField
label="Name"
name="name"
margin="normal"
variant="outlined"
onChange={handleChange("name")}
style={{ width: "100%", zIndex: 0 }}
value={values.name}
onBlur={() => {
console.log("name");
}}
/>
{errors.name}
</Grid>
<Grid item md={6} xs={12}>
<Select
placeholder="Year"
value={selectedYear}
onChange={selectedOption => {
handleYearChange(selectedOption);
// handleYearChange(selectedOption, values);
// values.year = selectedOption.value;
console.log("values", values.year);
handleChange("year");
}}
isSearchable={true}
options={yearOptions}
name="year"
isLoading={false}
loadingMessage={() => "Fetching year"}
noOptionsMessage={() => "Year appears here"}
/>
{errors.year}
</Grid>
<Grid
item
md={4}
style={{ marginTop: "24px", marginBottom: "10px" }}
xs={12}
>
<Button onClick={handleSubmit}>Save</Button>
</Grid>
</Grid>
</>
);
}}
</Formik>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here is the codesandbox :
PS: I'm new to Reactjs.
handleChange("year")(selectedOption.value);
it does not show the selected value onreact-select
box but reflects invalues
object. However if i dohandleChange("year")(selectedOption);
then it reflects the selected option onreact-select
and the values object seems to have nested object. Is there any way where thevalues
object has only string value and not the nested object? – Manure