在使用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>
);
}