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 状态,
- 您不需要单独管理表单状态
- 如果您提供自定义 onChange 函数,则必须调用 setFieldValue
- 您不需要将
value
传递给 <Field/>
组件,它是在内部完成的。
这里我用的是蚁酸。即使我违背了一些验证模式,甚至输入中的值也完全填充了规则 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 状态,
- 您不需要单独管理表单状态
- 如果您提供自定义 onChange 函数,则必须调用 setFieldValue
- 您不需要将
value
传递给<Field/>
组件,它是在内部完成的。