id: fastfield title:

custom_edit_url: https://github.com/jaredpalmer/formik/edit/master/docs/api/fastfield.md

在我们开始之前

<FastField />是为了表演优化. 然而,你真的不需要使用它,直到你这样做。只有在你熟悉反应的情况下才能继续shouldComponentUpdate()作品。有人警告过你。**

不严重。在继续之前,请检查官方反应文件的以下部分

概述

<FastField />是的优化版本<Field />用于大型表单(约 30 多个字段)或字段具有非常昂贵的验证要求时。<FastField />具有与相同的 API<Field>,但实现shouldComponentUpdate()在内部阻止所有其他重新呈现,除非直接更新<FastField />‘s formik 状态的相关部分/切片。

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

  • 改变到values.firstNameerrors.firstNametouched.firstNameisSubmitting.这是通过比较来确定的。注意:支持点路径。
  • 支柱被添加/移除到<FastField name="firstName" />
  • 这个name道具更改

除上述情况外,<FastField />当 Formik 状态的其他部分更改时不会重新呈现。但是,所有由<FastField />将触发重新渲染到其他“香草色”<Field />组件。

何时使用<FastField />

如果 A<Field />“独立”于所有其他<Field />在您的表单中,然后您可以使用<FastField />.

更具体地说,如果<Field />不更改行为或呈现基于更新到其他人的任何内容<Field /><FastField />Formik 状态的一部分,它不依赖于顶层的其他部分<Formik />状态(例如isValidating,请submitCount,然后您可以使用<FastField />作为替代品<Field />.

例子

  1. import React from 'react';
  2. import {Formik, Field, FastField, Form} from 'formik';
  3. const Basic = () => (
  4. <div>
  5. <h1>Sign Up</h1>
  6. <Formik
  7. initialValues={{
  8. firstName: '',
  9. lastName: '',
  10. email: ''
  11. }}
  12. validationSchema={Yup.object().shape({
  13. firstName: Yup.string().required(),
  14. middleInitial: Yup.string(),
  15. lastName: Yup.string().required(),
  16. email: Yup.string()
  17. .email()
  18. .required()
  19. })}
  20. onSubmit={values => {
  21. setTimeout(() => {
  22. alert(JSON.stringify(values, null, 2));
  23. }, 500);
  24. }}
  25. render={formikProps => (
  26. <Form>
  27. {/** This <FastField> only updates for changes made to
  28. values.firstName, touched.firstName, errors.firstName */}
  29. <label htmlFor="firstName">First Name</label>
  30. <FastField name="firstName" placeholder="Weezy" />
  31. {/** Updates for all changes because it's from the
  32. top-level formikProps which get all updates */}
  33. {form.touched.firstName && form.errors.firstName && (
  34. <div>{form.errors.firstName}</div>
  35. )}
  36. <label htmlFor="middleInitial">Middle Initial</label>
  37. <FastField
  38. name="middleInitial"
  39. placeholder="F"
  40. render={({field, form}) => (
  41. <div>
  42. <input {...field} />
  43. {/**
  44. * This updates normally because it's from the same slice of Formik state,
  45. * i.e. path to the object matches the name of this <FastField />
  46. */}
  47. {form.touched.middleInitial ? form.errors.middleInitial : null}
  48. {/** This won't ever update since it's coming from
  49. from another <Field>/<FastField>'s (i.e. firstName's) slice */}
  50. {form.touched.firstName && form.errors.firstName
  51. ? form.errors.firstName
  52. : null}
  53. {/* This doesn't update either */}
  54. {form.submitCount}
  55. {/* Imperative methods still work as expected */}
  56. <button
  57. type="button"
  58. onClick={form.setFieldValue('middleInitial', 'J')}
  59. >
  60. J
  61. </button>
  62. </div>
  63. )}
  64. />
  65. {/** Updates for all changes to Formik state
  66. and all changes by all <Field>s and <FastField>s */}
  67. <label htmlFor="lastName">LastName</label>
  68. <Field
  69. name="lastName"
  70. placeholder="Baby"
  71. render={({field, form}) => (
  72. <div>
  73. <input {...field} />
  74. {/** Works because this is inside
  75. of a <Field/>, which gets all updates */}
  76. {form.touched.firstName && form.errors.firstName
  77. ? form.errors.firstName
  78. : null}
  79. </div>
  80. )}
  81. />
  82. {/** Updates for all changes to Formik state and
  83. all changes by all <Field>s and <FastField>s */}
  84. <label htmlFor="email">Email</label>
  85. <Field name="email" placeholder="jane@acme.com" type="email" />
  86. <button type="submit">Submit</button>
  87. </Form>
  88. )}
  89. />
  90. </div>
  91. );