Skip to content

Instantly share code, notes, and snippets.

@pc035860
Last active July 23, 2019 08:12
Show Gist options
  • Save pc035860/8feda7c1bb884498f5434545d6e67a14 to your computer and use it in GitHub Desktop.
Save pc035860/8feda7c1bb884498f5434545d6e67a14 to your computer and use it in GitHub Desktop.
Enhanced Formik's <FastField />

Enhanced Formik's FastField

https://codesandbox.io/s/pensive-feather-9vo7n

Usage

Improve the <FastField /> re-render hinting with to additional props: names and deps.

names

List of the dependency name in the same formik schema.

<FastField
  name="firstName"
  names={['lastName', ...]}
  render={...}
/>

deps

List of the shallow compared values.

<FastField
  name="lastName"
  deps={[values.firstName, ...]}
  render={...}
/>
import React, { useMemo, useCallback } from 'react';
import PropTypes from 'prop-types';
import _ from 'lodash';
import { FastField as BaseFastField } from 'formik';
const nameShouldUpdate = (nextFormik, formik, name) => {
return (
_.get(formik.values, name) !== _.get(nextFormik.values, name) ||
_.get(formik.errors, name) !== _.get(nextFormik.errors, name) ||
_.get(formik.touched, name) !== _.get(nextFormik.touched, name)
);
};
const defaultShouldUpdate = (nextProps, props) => {
const { name } = props;
return (
nameShouldUpdate(nextProps.formik, props.formik, name) ||
Object.keys(props).length !== Object.keys(nextProps).length ||
props.formik.isSubmitting !== nextProps.formik.isSubmitting
);
};
const FastField = ({ names, deps: propDeps, ...restProps }) => {
// shallow check for updates
const deps = useMemo(() => propDeps, propDeps);
// shouldn't change after mount
const shouldUpdate = useCallback((nextProps, props) => {
if (props.deps !== nextProps.deps) {
return true;
}
if (defaultShouldUpdate(nextProps, props)) {
return true;
}
let update = false;
_.each(names, name => {
if (update) {
return;
}
if (nameShouldUpdate(nextProps.formik, props.formik, name)) {
update = true;
}
});
return update;
}, []);
return (
<BaseFastField shouldUpdate={shouldUpdate} {...restProps} deps={deps} />
);
};
FastField.propTypes = {
names: PropTypes.array, // specified formik names
deps: PropTypes.array, // specified value deps
};
FastField.defaultProps = {
names: [],
deps: [],
};
export default FastField;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment