使用React和Formik的无泪形式
您编写不包含至少一个表单的 Web 应用程序的情况并不常见。 通常,您的整个应用程序只是一系列表单。 这些表单中的每一个都需要状态管理、事件处理程序,并且通常还需要某种客户端数据验证。 Formik 旨在在一个小包装中完成所有这些工作,并且正如他们所声称的那样,“没有眼泪”。
入门
要开始使用 formik
,我们需要通过 npm
或 yarn
将其添加到我们的项目中:
$ npm install --save formik # or $ yarn add formik
添加依赖项后,请务必将其导入您将要使用它的项目中。 在本文中,我们将同时使用 Formik
和 Form
辅助组件:
import { Formik, Form } from "formik";
Form
组件是标准 form
元素的包装器,它自动连接附加到 Formik
组件的 onSubmit
处理程序,从而为我们节省更多时间。
Formik 组件
Formik 的真正魔力发生在 Formik
组件中。 该组件将用于包装您的表单并通过渲染道具公开状态值和处理程序。
所述组件可以使用属性来设置我们的默认值、验证提交的值并处理我们的提交。
以下是 Formik
组件如何查找我们稍后将创建的基本登录表单:
<Formik // Sets up our default values initialValues={{ email: "", password: "" }} // Validates our data validate={values => { const errors = {}; if (!values.email) errors.email = "Required"; if ( !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) ) { errors.email = "You must supply a valid email address"; } if (values.password.length < 8) { errors.password = "Passwords must be at least 8 characters"; } if (values.email === values.password) { errors.password = "Your password shouldn't be the same as your email"; } return errors; }} // Handles our submission onSubmit={(values, { setSubmitting }) => { // This is where you could wire up axios or superagent console.log("Submitted Values:", values); // Simulates the delay of a real request setTimeout(() => setSubmitting(false), 3 * 1000); }} > {props => ( <div>This is where your Form and form elements will go!</div> )} </Formik>
如果您熟悉 yup 或 joi 之类的对象模式验证器,那毫无价值,您可以跳过 validate
属性并传入 validationSchema
反而。
表单组件
如前所述,Form
组件是 form
元素的直接替代品,它可以自动连接诸如 onSubmit
处理程序之类的东西。
像往常一样使用它来包装表单的输入:
<Formik> {props => ( <Form> <label>My Input</label> <input type="text" /> </Form> )} </Formik>
输入状态
开箱即用,Formik 的渲染属性公开事件处理程序来管理对表单输入的更改,无论它们是否被“触摸”、它们的值和任何错误。
对于整个表单,您将能够判断表单是否处于验证或提交的过程中,以及让您轻松重置表单的事件处理程序。
props.values
和 props.errors
是具有与表单字段对应的属性的对象。
props.handleChange
和 props.handleBlur
可以传递给 onChange
和 onBlur
属性以跟踪更改以及输入是否被“触摸”。
当您只想在用户与元素交互后显示错误而不是在页面加载时(恕我直言,这是首选)时,此“触摸”值会派上用场。
当用户修改表单时,props.dirty
被设置为 true。
状态值 props.isValidating
和 props.isSubmitting
让您知道用户处于进程的哪个阶段。 非常适合显示加载程序或禁用表单或单个按钮。
把它放在一起
这是一个带有电子邮件和密码的简单登录表单在正式 Formiked 后的样子:
<Formik // Sets up our default values initialValues={{ email: "", password: "" }} // Validates our data validate={values => { const errors = {}; if (!values.email) errors.email = "Required"; if ( !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email) ) { errors.email = "You must supply a valid email address"; } if (values.password.length < 8) { errors.password = "Passwords must be at least 8 characters"; } if (values.email === values.password) { errors.password = "Your password shouldn't be the same as your email"; } return errors; }} // Handles our submission onSubmit={(values, { setSubmitting }) => { // This is where you could wire up axios or superagent console.log("Submitted Values:", values); // Simulates the delay of a real request setTimeout(() => setSubmitting(false), 3 * 1000); }} > {props => ( <Form> <label htmlFor="email">Email</label> <div> <input name="email" type="email" placeholder="Enter your account email" value={props.values.email} onChange={props.handleChange} onBlur={props.handleBlur} style={{ borderColor: props.errors.email && props.touched.email && "red" }} /> {props.errors.email && props.touched.email && ( <div style={{ color: "red" }}>{props.errors.email}</div> )} </div> <label htmlFor="password">Password</label> <div> <input name="password" type="password" placeholder="Enter your account password" value={props.values.password} onChange={props.handleChange} onBlur={props.handleBlur} style={{ borderColor: props.errors.password && props.touched.password && "red" }} /> {props.errors.password && props.touched.password && ( <div style={{ color: "red" }}>{props.errors.password}</div> )} </div> <input type="submit" value="Submit" disabled={props.isSubmitting} /> <input type="reset" value="Reset" onClick={props.handleReset} disabled={!props.dirty || props.isSubmitting} /> </Form> )} </Formik>
结论
Formik 提供了一种熟悉的、基于 渲染属性 的方法来构建表单。
您通常最终编写的大多数冗余样板和语句管理逻辑都得到了很好的处理,同时仍然提供了足够的动力来对表单进行一些非常复杂的状态管理。
如果您想对本文中的代码进行测试,可以在 CodeSandbox 上查看。
干杯!