<FastField />
用于性能优化。但是,在你真正需要之前,你真的不需要使用它。只有在你熟悉 React 的 shouldComponentUpdate()
工作原理时,才继续进行。我已经警告过你了。
不。说真的。请在继续之前查看官方 React 文档的以下部分
<FastField />
是 <Field />
的优化版本,旨在用于大型表单(约 30 个以上字段)或当字段具有非常昂贵的验证要求时。<FastField />
与 <Field>
具有完全相同的 API,但在内部实现了 shouldComponentUpdate()
以阻止所有额外的重新渲染,除非 <FastField />
的相关部分/Formik 状态切片有直接更新。
例如,<FastField name="firstName" />
仅在以下情况下重新渲染:
values.firstName
、errors.firstName
、touched.firstName
或 isSubmitting
发生更改。这是通过浅比较确定的。注意:支持点路径。<FastField name="firstName" />
添加/删除属性name
属性发生变化除了上述情况外,当 Formik 状态的其他部分发生更改时,<FastField />
不会重新渲染。但是,由 <FastField />
触发的所有更新都会触发对其他“普通”<Field />
组件的重新渲染。
<FastField />
如果 <Field />
与表单中的所有其他 <Field />
“独立”,则可以使用 <FastField />
.
更具体地说,如果 <Field />
不更改基于其他 <Field />
或 <FastField />
的 Formik 状态切片更新的行为或渲染任何内容,并且不依赖于顶级 <Formik />
状态的其他部分(例如 isValidating
、submitCount
),则可以使用 <FastField />
作为 <Field />
的直接替换。
import React from 'react';import { Formik, Field, FastField, Form } from 'formik';import * as Yup from 'yup';const Basic = () => (<div><h1>Sign Up</h1><FormikinitialValues={{firstName: '',lastName: '',email: '',}}validationSchema={Yup.object().shape({firstName: Yup.string().required(),middleInitial: Yup.string(),lastName: Yup.string().required(),email: Yup.string().email().required(),})}onSubmit={values => {setTimeout(() => {alert(JSON.stringify(values, null, 2));}, 500);}}>{formikProps => (<Form>{/** This <FastField> only updates for changes made tovalues.firstName, touched.firstName, errors.firstName */}<label htmlFor="firstName">First Name</label><FastField name="firstName" placeholder="Weezy" />{/** Updates for all changes because it's from thetop-level formikProps which get all updates */}{formikProps.touched.firstName && formikProps.errors.firstName && (<div>{formikProps.errors.firstName}</div>)}<label htmlFor="middleInitial">Middle Initial</label><FastField name="middleInitial" placeholder="F">{({ field, form, meta }) => (<div><input {...field} />{/*** This updates normally because it's from the same slice of Formik state,* i.e. path to the object matches the name of this <FastField />*/}{meta.touched ? meta.error : null}{/** This won't ever update since it's coming fromfrom another <Field>/<FastField>'s (i.e. firstName's) slice */}{form.touched.firstName && form.errors.firstName? form.errors.firstName: null}{/* This doesn't update either */}{form.submitCount}{/* Imperative methods still work as expected */}<buttontype="button"onClick={form.setFieldValue('middleInitial', 'J')}>J</button></div>)}</FastField>{/** Updates for all changes to Formik stateand all changes by all <Field>s and <FastField>s */}<label htmlFor="lastName">LastName</label><Field name="lastName" placeholder="Baby">{({ field, form, meta }) => (<div><input {...field} />{/** Works because this is insideof a <Field/>, which gets all updates */}{form.touched.firstName && form.errors.firstName? form.errors.firstName: null}</div>)}</Field>{/** Updates for all changes to Formik state andall changes by all <Field>s and <FastField>s */}<label htmlFor="email">Email</label><button type="submit">Submit</button></Form>)}</Formik></div>);