React Formik教程系列之二:Formik Components


在使用React进行开发的时候,如果是简单的表单还好。如果遇到复杂的表单,比如分好几个步骤的表单,联动效果的字段,多层结构的字段等等,就需要一个好的框架的支持了。下面介绍一下:Formik中的组件。

React Formik组件
React Formik组件

Formik组件

除了useFormik Hook,我们还可以使用Formik组件。其实Formik组件在这里相当于是一个ContextProvider,能够为其他组件提供相应的属性。

JavaScript
<Formik
      initialValues={initialValues}
      onSubmit={onSubmit}
      validationSchema={validationSchema}
    >
// ...
</Formik>    

Form组件

Form组件封装了HTML的form,因此在使用Form组件的时候,无需指定onSubmit={formik.handleSubmit}类似的属性。在其父组件Formik已经指定过了。

Field组件

Field组件的功能包括:

  • 获取用户输入
  • 实现类似这样的操作:{…formik.getFieldProps(‘age’)}

其实Field就是HTML控件的wrapper,所有传递给Field组件的属性都会被传递给对应的HTML组件,比如:placeholder。

默认情况下,Field会被渲染为inputbox,如果想要更改为其他HTML组件,则需要使用as :

JavaScript
<Field as='textarea' id='feedback' name='feedback' />

Field组件会向其子组件传递一个render props,其中包含如下信息:

  • field
  • form
  • meta
JavaScript
<Field id='feedback' name='feedback'>
  {
    (props) => {
      const { field, form, meta } = props;
      return(
        <div>
          <input type='text' id='feedback' {...field} />
          {
            meta.touched && meta.error ? <div>{meta.error}</div> : null
          }
        </div>
      );
    }
  }
</Field>

ErrorMessage组件

这个组件能够封装相应的错误处理逻辑。

JavaScript
<ErrorMessage name='age'/>

在默认情况下,错误信息只是一个文本节点。如果想使用其他html标签,可以使用component来指定。这里可以使用html组件,也可以使用自己的组件。

JavaScript
<ErrorMessage name='age' component='div' />

或者使用自己的组件:

JavaScript
export default function ErrorComponent(props) {
  return (
    <div className='error'>
      { props.children }
    </div>
  )
}
JavaScript
<ErrorMessage name='age' component={ErrorComponent} />

这样就可以非常灵活的定义自己的出错信息样式了。

也可以在ErrorMessage的子组件中定义一个函数,这样也可以返回自定义样式:

JavaScript
<ErrorMessage name='age'>
  {
    errorMsg => <div className='error'>{ errorMsg }</div>
  }
</ErrorMessage>

使用以上组件优化后的代码

JavaScript
import React from "react";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";

export default function NormalForm() {
  const initialValues = {
    name: "",
    email: "",
    age: 18,
  };
  const onSubmit = (values) => {
    console.log(values);
  };

  const validationSchema = Yup.object({
    name: Yup.string().required("必填字段."),
    email: Yup.string().email("错误邮件地址").required("必填字段"),
    age: Yup.number().required("必填字段"),
  });

  return (
    <Formik
      initialValues={initialValues}
      onSubmit={onSubmit}
      validationSchema={validationSchema}
    >
      <Form>
        <label htmlFor="name">Name</label>
        <Field
          type="text"
          id="name"
          name="name"
        />
        <ErrorMessage name='name'/>
        <br />

        <label htmlFor="email">Email</label>
        <Field
          type="text"
          id="email"
          name="email"
        />
        <ErrorMessage name='email'/>
        <br />

        <label htmlFor="age">Age</label>
        <Field
          type="age"
          id="age"
          name="age"
        />
        <ErrorMessage name='age'/>
        <br />

        <button type="submit">Submit</button>
      </Form>
    </Formik>
  );
}

文章作者: 逻思
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 逻思 !