Permalink
Browse files

Rerender <FastField /> when isSubmitting has changed (#915)

  • Loading branch information...
stalmok authored and jaredpalmer committed Sep 19, 2018
1 parent c2b27df commit 63a87eb0aa9a28b4bcfd0c20687ec1776465bbcf
Showing with 35 additions and 9 deletions.
  1. +12 −0 .storybook/example.stories.js
  2. +2 −2 docs/api/fastfield.md
  3. +19 −6 examples/FastField.js
  4. +2 −1 src/FastField.tsx
@@ -7,6 +7,7 @@ import Arrays from '../examples/Arrays';
import Basic from '../examples/Basic.js';
import CustomInputs from '../examples/CustomInputs';
import ErrorMessage from '../examples/ErrorMessage';
import FastField from '../examples/FastField';
import MultistepWizard from '../examples/MultistepWizard';
import SchemaValidation from '../examples/SchemaValidation';
import SyncValidation from '../examples/SyncValidation';
@@ -18,6 +19,7 @@ const ArraysCode = require('!raw-loader!../examples/Arrays');
const BasicCode = require('!raw-loader!../examples/Basic.js');
const CustomInputsCode = require('!raw-loader!../examples/CustomInputs');
const ErrorMessageCode = require('!raw-loader!../examples/ErrorMessage');
const FastFieldCode = require('!raw-loader!../examples/FastField');
const MultistepWizardCode = require('!raw-loader!../examples/MultistepWizard');
const SchemaValidationCode = require('!raw-loader!../examples/SchemaValidation');
const SyncValidationCode = require('!raw-loader!../examples/SyncValidation');
@@ -117,6 +119,16 @@ storiesOf('Example', module)
</div>
);
})
.add('FastField', () => {
return (
<div className="formik-example">
<main>
<FastField />
</main>
<Code>{cleanExample(FastFieldCode)}</Code>
</div>
);
})
.add('Multistep Wizard', () => {
return (
<div className="formik-example">
@@ -18,7 +18,7 @@ title: <FastField />

For example, `<FastField name="firstName" />` will only re-render when there are:

* Changes to `values.firstName`, `errors.firstName`, or `touched.firstName`. This is determined by shallow comparison. Note: dotpaths are supported.
* Changes to `values.firstName`, `errors.firstName`, `touched.firstName`, or `isSubmitting`. This is determined by shallow comparison. Note: dotpaths are supported.
* A prop is added/removed to the `<FastField name="firstName" />`
* The `name` prop changes

@@ -28,7 +28,7 @@ Other than for these aforementioned situations, `<FastField />` will not re-rend

**If a `<Field />` is "independent" of all other `<Field />`'s in your form, then you can use `<FastField />`**.

More specifically, if the `<Field />` does not change behavior or render anything that is based on updates to another `<Field />` or `<FastField />`'s slice of Formik state AND it does not rely on other parts of top-level `<Formik />` state (e.g. `isSubmitting`, `isValidating`, `submitCount`), then you can use `<FastField />` as a drop-in replacement to `<Field />`.
More specifically, if the `<Field />` does not change behavior or render anything that is based on updates to another `<Field />` or `<FastField />`'s slice of Formik state AND it does not rely on other parts of top-level `<Formik />` state (e.g. `isValidating`, `submitCount`), then you can use `<FastField />` as a drop-in replacement to `<Field />`.

## Example

@@ -1,5 +1,5 @@
import React from 'react';
import { Formik, Field, FastField, Form } from 'formik';
import { Formik, FastField, Form } from 'formik';
import { Debug } from './Debug';

class Input extends React.Component {
@@ -8,8 +8,8 @@ class Input extends React.Component {
const { field, form, ...rest } = this.props;
return (
<div>
{this.renders++}
<input {...field} {...rest} />
<p># of renders: {this.renders++}</p>
</div>
);
}
@@ -24,25 +24,38 @@ const Basic = () => (
lastName: '',
email: '',
}}
onSubmit={values => {
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
setSubmitting(false);

alert(JSON.stringify(values, null, 2));
}, 500);
}}
render={() => (
render={({ isSubmitting }) => (
<Form>
<label htmlFor="firstName">First Name</label>
<FastField name="firstName" placeholder="Jane" component={Input} />
<FastField
name="firstName"
placeholder="Jane"
component={Input}
disabled={isSubmitting}
/>

<label htmlFor="lastName">Last Name</label>
<FastField name="lastName" placeholder="Doe" component={Input} />
<FastField
name="lastName"
placeholder="Doe"
component={Input}
disabled={isSubmitting}
/>

<label htmlFor="email">Email</label>
<FastField
name="email"
placeholder="jane@acme.com"
type="email"
component={Input}
disabled={isSubmitting}
/>

<button type="submit">Submit</button>
@@ -113,7 +113,8 @@ class FastFieldInner<Values = {}, Props = {}> extends React.Component<
getIn(props.formik.errors, this.props.name) ||
getIn(this.props.formik.touched, this.props.name) !==
getIn(props.formik.touched, this.props.name) ||
Object.keys(this.props).length !== Object.keys(props).length
Object.keys(this.props).length !== Object.keys(props).length ||
this.props.formik.isSubmitting !== props.formik.isSubmitting
) {
return true;
} else {

0 comments on commit 63a87eb

Please sign in to comment.