使用带有Yup和React-select的Formik进行验证

Nik*_*Nik 1 reactjs react-select material-ui yup formik

我与使用反应表单验证工作Yup,沿Formikreact-select表单中的一个元素也需要验证。为了验证我正在做使用validationSchemaFormik,以验证形式值的变化。我只需要选择字段的值作为字符串,所以不能采用完整的对象(键值)。选择字段运行良好,但是没有清除验证错误消息。问题是如何使用现有方法验证选择字段?

以下是最少的代码示例。

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);
Run Code Online (Sandbox Code Playgroud)

这是codeandbox:

编辑throbbing-shadow-6f6yw

PS:我是Reactjs的新手。

Man*_*tel 7

简单的解决办法::它的工作原理,,,,,甚至对任何其他输入类型输入字段的像反应色,,或日期选择器或任何东西......通过这个逻辑..你需要傻瓜formik,它会认为这是下面给出了一个事件,,, 示例,,,,, 这里 - handleChange 来自 formik

validationSchema = yup.object({
     year_value :yup.object().required('*year value is required.')
})
Run Code Online (Sandbox Code Playgroud)

<Select 
    className="  "
    name="year_value"
    id="year_value"
    placeholder='Choose year value'
    value={values.year_value}
    onBlur={handleBlur}
    onChange={selectedOption => {
        let event = { target : { name:'year_value',value: selectedOption}}
        handleChange(event)
    }}
    onBlur={()=>{
      handleBlur({ target: {name:'year_value'} });
    }}
    options={yearOptions}
/>

Run Code Online (Sandbox Code Playgroud)


jag*_*ler 5

更改

handleChange("year")
Run Code Online (Sandbox Code Playgroud)

handleChange("year")(selectedOption.value);
Run Code Online (Sandbox Code Playgroud)

当前,yearFormik值中的字段未更新。handleChange()函数返回一个新函数,可以使用一个值调用该函数以更新Formik状态。

发现这些东西的最简单方法是使用以下代码输出Formik道具:

<pre>{JSON.stringify(props, null, 2)}</pre>
Run Code Online (Sandbox Code Playgroud)

有关示例,请参见此沙箱。在沙盒中,我完全删除了对自定义年份状态的需要。我建议仅使用Formik状态来操纵值。仅使用Formik状态,保存时可能只需要提取年份部分,因为默认情况下react-select使用完整的对象。

  • `react-select` 包默认需要完整的对象。作者编写了一个单独的包来仅传递值部分,请查看:https://github.com/jossmac/react-select-simple-value (2认同)