<FastField />

在开始之前

<FastField /> 用于性能优化。但是,在你真正需要之前,你真的不需要使用它。只有在你熟悉 React 的 shouldComponentUpdate() 工作原理时,才继续进行。我已经警告过你了。

不。说真的。请在继续之前查看官方 React 文档的以下部分

概述

<FastField /><Field /> 的优化版本,旨在用于大型表单(约 30 个以上字段)或当字段具有非常昂贵的验证要求时。<FastField /><Field> 具有完全相同的 API,但在内部实现了 shouldComponentUpdate() 以阻止所有额外的重新渲染,除非 <FastField /> 的相关部分/Formik 状态切片有直接更新。

例如,<FastField name="firstName" /> 仅在以下情况下重新渲染:

  • values.firstNameerrors.firstNametouched.firstNameisSubmitting 发生更改。这是通过浅比较确定的。注意:支持点路径。
  • <FastField name="firstName" /> 添加/删除属性
  • name 属性发生变化

除了上述情况外,当 Formik 状态的其他部分发生更改时,<FastField /> 不会重新渲染。但是,由 <FastField /> 触发的所有更新都会触发对其他“普通”<Field /> 组件的重新渲染。

何时使用 <FastField />

如果 <Field /> 与表单中的所有其他 <Field /> “独立”,则可以使用 <FastField />.

更具体地说,如果 <Field /> 不更改基于其他 <Field /><FastField /> 的 Formik 状态切片更新的行为或渲染任何内容,并且不依赖于顶级 <Formik /> 状态的其他部分(例如 isValidatingsubmitCount),则可以使用 <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>
<Formik
initialValues={{
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 to
values.firstName, touched.firstName, errors.firstName */}
<label htmlFor="firstName">First Name</label>
<FastField name="firstName" placeholder="Weezy" />
{/** Updates for all changes because it's from the
top-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 from
from 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 */}
<button
type="button"
onClick={form.setFieldValue('middleInitial', 'J')}
>
J
</button>
</div>
)}
</FastField>
{/** Updates for all changes to Formik state
and 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 inside
of 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 and
all changes by all <Field>s and <FastField>s */}
<label htmlFor="email">Email</label>
<Field name="email" placeholder="[email protected]" type="email" />
<button type="submit">Submit</button>
</Form>
)}
</Formik>
</div>
);
此页面是否有帮助?

订阅我们的时事通讯

最新的 Formik 新闻、文章和资源,发送到您的收件箱。

版权所有 © 2020 Formium, Inc. 保留所有权利。