选项 1
您可以在每个表单输入中添加validate 调用,这样当用户更改输入时,status 消息将被清除。
import React from "react";
import ReactDOM from "react-dom";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
const schema = Yup.object().shape({
name: Yup.string().required("Name"),
age: Yup.number().required("Number").positive().integer()
});
const MyForm = () => (
<div>
<Formik
initialValues={{ name: "", age: "" }}
validationSchema={schema}
onSubmit={(values, actions) => {
console.log("submited", values);
actions.setStatus("")
try {
throw new Error("Something went wrong")
}
catch (error) {
actions.setStatus(error.message);
}
}}
render={({
status,
isSubmitting,
setStatus,
dirty,
values,
handleReset,
errors,
touched
}) => {
const field_props_with_validation = function() {
const name = arguments[0];
const type = arguments[1] || "text";
const placeholder = arguments[2] || "";
return {
name,
type,
placeholder,
validate: () => {
setStatus("");
}
}
}
return (
<Form>
{status}
{["name", "age"].map((field, key) => (
<div key={key}>
<Field {...field_props_with_validation(field)} />
<ErrorMessage name={field} component="div" />
</div>
))}
<button type="submit">Enter</button>
</Form>
);
}}
/>
</div>
);
function App() {
return (
<div className="App">
<h1>Registration Form</h1>
<MyForm />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
选项 2
validation 可以在使用validateOnChange 道具更改表单输入时为disabled,并且只有在用户提交表单时validate。
注意:在这种情况下,您必须处理验证,在用户重新提交表单之前,状态不会被清除。
import React from "react";
import ReactDOM from "react-dom";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
const schema = Yup.object().shape({
name: Yup.string().required("Name"),
age: Yup.number().required("Number").positive().integer()
});
const MyForm = () => (
<div>
<Formik
initialValues={{ name: "", age: "" }}
validateOnChange={false}
onSubmit={async (values, actions) => {
actions.setStatus("");
await schema.validate(values, {
abortEarly: false // not to stop on single validation fail
// and return single error message
})
.then(() => {
try {
throw new Error("Some error")
}
catch (error) {
actions.setStatus(error.message);
}
})
.catch(err => {
let errors = {};
Object.keys(values).forEach((key, idx) => {
if (err && err.errors && err.errors[idx]) {
errors[key] = err.errors[idx];
}
});
actions.setErrors(errors)
})
}}
render={({
status,
isSubmitting,
dirty,
values,
handleReset,
errors,
touched
}) => {
return (
<Form>
{status}
{["name", "age"].map((field, key) => (
<div key={key}>
<Field name={field} type="text" placeholder={field} />
<ErrorMessage name={field} component="div" />
</div>
))}
<button type="submit">Enter</button>
</Form>
);
}}
/>
</div>
);
function App() {
return (
<div className="App">
<h1>Registration Form</h1>
<MyForm />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);