使用 React 和 Formik 制作无泪表单

你不经常写一个不包含至少一个表单的Web应用程序. 更常见的是,你的整个应用程序只是一系列表单. 这些表单中的每一个都需要状态管理,事件处理器,并且,通常,某种类型的客户端数据验证。

开始的

要开始使用formik,我们需要通过npmyarn将其添加到我们的项目中:

1$ npm install --save formik
2# or
3$ yarn add formik

一旦添加了依赖性,请确保将其导入到您要使用的项目中,对于本文,我们将使用FormikForm辅助组件:

1import { Formik, Form } from "formik";

Form组件是标准的form元素的包装器,自动连接附加到Formik组件的onSubmit处理器,节省了我们更多的时间。

Formik 组件

Formik的真正魔力发生在Formik组件中,这个组件将被用来包装您的表格,并通过渲染符号暴露状态值和处理器。

该组件可以使用属性来设置我们的默认值,验证提交的值,并处理我们的提交。

以下是Formik组件将如何寻找我们将在稍后创建的基本登录表格:

 1<Formik
 2  // Sets up our default values
 3  initialValues={{ email: "", password: "" }}
 4
 5  // Validates our data
 6  validate={values => {
 7    const errors = {};
 8
 9    if (!values.email) errors.email = "Required";
10
11    if (
12      !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)
13    ) {
14      errors.email = "You must supply a valid email address";
15    }
16
17    if (values.password.length < 8) {
18      errors.password = "Passwords must be at least 8 characters";
19    }
20
21    if (values.email === values.password) {
22      errors.password =
23        "Your password shouldn't be the same as your email";
24    }
25
26    return errors;
27  }}
28
29  // Handles our submission
30  onSubmit={(values, { setSubmitting }) => {
31    // This is where you could wire up axios or superagent
32    console.log("Submitted Values:", values);
33    // Simulates the delay of a real request
34    setTimeout(() => setSubmitting(false), 3 * 1000);
35  }}
36>
37  {props => (
38    <div>This is where your Form and form elements will go!</div>
39  )}
40</Formik>

毫无价值,如果你熟悉对象方案验证器,如 yupjoi你可以跳过验证属性,并通过一个验证方案

形式组件

如前所述,Form组件是form元素的落入替代品,它自动连接诸如onSubmit处理器等东西。

使用它来包装您的表单的输入,就像你通常会:

1<Formik>
2  {props => (
3    <Form>
4      <label>My Input</label>
5      <input type="text" />
6    </Form>
7  )}
8</Formik>

入口的状态

窗口之外,Formik的渲染属性暴露了事件处理器来管理您的表单输入的更改,无论它们是否被触摸,它们的值和任何错误。

对于整个表单,您将能够知道表单是否正在验证或提交,并有一个事件处理器,允许您轻松重置表单。

props.valuesprops.errors 是具有与表单字段相符的属性的对象。

props.handleChangeprops.handleBlur 可以转移到 onChangeonBlur 属性,以跟踪更改,以及输入是否被触摸了。

触摸值在用户与某个元素互动后,而不是在页面加载时(IMHO优先)只需要显示错误时非常有用。

props.dirty 设置为当用户更改表单时为真实。

状态值 props.isValidatingprops.isSubmitting 允许您知道用户处于什么阶段的过程。

把一切都带到一起

这是一个简单的登录表格与电子邮件和密码看起来像一旦正式 Formiked:

 1<Formik
 2  // Sets up our default values
 3  initialValues={{ email: "", password: "" }}
 4
 5  // Validates our data
 6  validate={values => {
 7    const errors = {};
 8
 9    if (!values.email) errors.email = "Required";
10
11    if (
12      !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)
13    ) {
14      errors.email = "You must supply a valid email address";
15    }
16
17    if (values.password.length < 8) {
18      errors.password = "Passwords must be at least 8 characters";
19    }
20
21    if (values.email === values.password) {
22      errors.password =
23        "Your password shouldn't be the same as your email";
24    }
25
26    return errors;
27  }}
28
29  // Handles our submission
30  onSubmit={(values, { setSubmitting }) => {
31    // This is where you could wire up axios or superagent
32    console.log("Submitted Values:", values);
33    // Simulates the delay of a real request
34    setTimeout(() => setSubmitting(false), 3 * 1000);
35  }}
36>
37  {props => (
38    <Form>
39      <label htmlFor="email">Email</label>
40      <div>
41        <input
42          name="email"
43          type="email"
44          placeholder="Enter your account email"
45          value={props.values.email}
46          onChange={props.handleChange}
47          onBlur={props.handleBlur}
48          style={{
49            borderColor:
50              props.errors.email && props.touched.email && "red"
51          }}
52        />
53        {props.errors.email && props.touched.email && (
54          <div style={{ color: "red" }}>{props.errors.email}</div>
55        )}
56      </div>
57      <label htmlFor="password">Password</label>
58      <div>
59        <input
60          name="password"
61          type="password"
62          placeholder="Enter your account password"
63          value={props.values.password}
64          onChange={props.handleChange}
65          onBlur={props.handleBlur}
66          style={{
67            borderColor:
68              props.errors.password && props.touched.password && "red"
69          }}
70        />
71        {props.errors.password && props.touched.password && (
72          <div style={{ color: "red" }}>{props.errors.password}</div>
73        )}
74      </div>
75      <input
76        type="submit"
77        value="Submit"
78        disabled={props.isSubmitting}
79      />
80      &nbsp;
81      <input
82        type="reset"
83        value="Reset"
84        onClick={props.handleReset}
85        disabled={!props.dirty || props.isSubmitting}
86      />
87    </Form>
88  )}
89</Formik>

结论

Formik 提供了熟悉的,基于 render prop的方法来构建形式。

您通常写出的多余的锅炉板和陈述管理逻辑大部分都很好地照顾,同时仍然在帽子下提供足够的功率,以便在您的表单上进行一些相当复杂的状态管理。

如果你想给本文中的代码一个测试旋转,你可以检查它在 CodeSandbox

欢呼!

Published At
Categories with 技术
Tagged with
comments powered by Disqus