formic 总是显示 form 无效

Formic always shows that form is invalid

这里我用的是蚁酸。即使我违背了一些验证模式,甚至输入中的值也完全填充了规则 formic 结合 YUP 总是说表单无效,即使表单值有效。我是初学者。因此,如果您能提供一些深入的答案,我将不胜感激。

谢谢

import React, { useEffect, useState } from 'react'
import './index.css'
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import axios from 'axios'


const Inedex = () => {

const [projects, setProjects] = useState([])
const [memebers, setMemebers] = useState([])

const [formData, setFormData] = useState({
    projectId: "",
    title: "",
    actualOutcomes: "",
    expectedOutcomes: ""
})


const setData = (key, value) => {
    setFormData({ ...formData, [key]: value })
    console.log(formData, { key, value })
}


useEffect(() => {
    getProjects();
}, [])

const getProjects = () => {
    axios.get("http://localhost:5000/project/all/names").then(res => {
        console.log(res.data)
        setProjects([...res.data])
    })
}

const handleProjectChange = (value) => {
    setData("projectId", value);
    axios.post("http://localhost:5000/project/roles", {
        "projectId": value,
        "role": "DEV"
    }).then(res => {
        console.log(res.data)
        setMemebers(res.data)
    })

}

const submitForm = (values) => {
    console.log(values);
};

const initialValues = {
    project:"",
    developer:"",
    email: "",
    title: "",
    project: "",
    developer: "",
    title: "",
    actualOutcomes: "",
    expectedOutcomes: ""
};


const DynamicProjectOptions = () => {
    return (
        projects.map(project => {
            return (
                <option value={project.id} key={projects.name} >{project.name}</option>
            )
        })
    )
}


const DynamicMembers = () => {
    return (
        memebers.map(memeber => {
            return (
                <option value={memeber.id} key={memeber.name} >{memeber.name}</option>
            )
        })
    )
}


const signInSchema = Yup.object().shape({
    project: Yup.string().min(1, 'Too Short!').required("Project is required"),
    developer: Yup.string().min(1, 'Too Short!').required("Developer is required"),
    title: Yup.string().min(5, 'Too Short!').required("Title is required"),
    actualOutcomes: Yup.string().min(5, 'Too Short!').required("Actual outcomes is required"),
    expectedOutcomes: Yup.string().min(5, 'Too Short!').required("Expected outcomes is required"),

});



return (
    <Formik
        initialValues={initialValues}
        validationSchema={signInSchema}
        onSubmit={(values) => alert(values)}
    >
        {({ errors, touched, isValid, dirty }) => {

            return (<Form>
                <div className="container">
                    <h2>Report a bug</h2>

                    {/* Project  */}

                    {isValid}
                    <div className="form-row">
                        <label htmlFor="project">Project</label>
                        <Field
                            name="project"
                            component="select"
                            id="project"
                            className={(errors.email && touched.email ? "is-invalid" : null) + " form-control "}
                            onChange={e => { handleProjectChange(e.target.value) }}
                            value={formData.projectId}
                        >
                            <DynamicProjectOptions />
                        </Field>

                        {JSON.stringify(formData.selectedProject)}
                        <ErrorMessage name="project" component="span" className="invalid-feedback" />
                    </div>


                    {/* Developer  */}
                    <div className="form-row">
                        <label htmlFor="developer">Developer</label>

                        <Field
                            name="developer"
                            component="select"
                            id="developer"
                            className={(errors.email && touched.email ? "is-invalid" : null) + " form-control "}
                        >
                            <DynamicMembers />
                        </Field>

                        <ErrorMessage name="developer" component="span" className="invalid-feedback" />
                    </div>



                    <div className="form-row">
                        <label htmlFor="title">Title</label>
                        <Field
                            type="text"
                            name="title"
                            id="email"
                            className={(errors.email && touched.email ? "is-invalid" : null) + " form-control "}
                            onChange={(e) => { setData("title", e.target.value) }}
                            value={formData.title}
                        />
                        <ErrorMessage name="title" component="span" className="invalid-feedback" />
                    </div>


                    <div className="form-row">
                        <label htmlFor="email">Actual outcomes</label>
                        <Field
                            type="text"
                            name="actualOutcomes"
                            id="actualOutcomes"
                            className={(errors.email && touched.email ? "is-invalid" : null) + " form-control "}
                            onChange={(e) => { setData("actualOutcomes", e.target.value) }}
                            value={formData.actualOutcomes}
                        />
                        <ErrorMessage name="actualOutcomes" component="span" className="invalid-feedback" />
                    </div>

                    <div className="form-row">
                        <label htmlFor="email">Expected outcomes</label>
                        <Field
                            type="text"
                            name="expectedOutcomes"
                            id="expectedOutcomes"
                            className={(errors.email && touched.email ? "is-invalid" : null) + " form-control "}
                            onChange={(e) => { setData("expectedOutcomes", e.target.value) }}
                            value={formData.expectedOutcomes}
                        />
                        <ErrorMessage name="expectedOutcomes" component="span" className="invalid-feedback" />
                    </div>

                    {JSON.stringify({dirty , isValid , touched})}
                    {/* {JSON.stringify(Object.keys(errors))} */}
                    <button
                        type="submit"
                        className={!(dirty && isValid) ? "disabled-btn" : ""}
                        disabled={!(dirty && isValid)}
                    >
                        Sign In
                    </button>
                </div>
            </Form>
            );
        }}
    </Formik>
      );
     };

   export default Inedex;

检查沙盒,https://codesandbox.io/s/sharp-leftpad-0j792?file=/src/App.js

这里有多个问题,<Field/> 组件自动管理 onChange 以设置为 formik 状态,

  1. 您不需要单独管理表单状态
  2. 如果您提供自定义 onChange 函数,则必须调用 setFieldValue
  3. 您不需要将 value 传递给 <Field/> 组件,它是在内部完成的。