Skip to content

Instantly share code, notes, and snippets.

@rzane
Created November 14, 2017 15:12
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rzane/f98a8b961572e8dbb7a91e2132bfaf4e to your computer and use it in GitHub Desktop.
Save rzane/f98a8b961572e8dbb7a91e2132bfaf4e to your computer and use it in GitHub Desktop.
<Field /> component that supports nested values for formik
import React from 'react';
import PropTypes from 'prop-types';
import { set, get } from 'lodash/fp';
/**
* This is a copy-pasta job of Formik's Field component. It's needed in
* order to handle nested values. Future versions of formik will support
* this.
*/
const update = (key, value, values) => {
const [name, ...path] = key.split('.');
if (path.length) {
return [name, set(path, value, values[name])];
}
return [key, value];
};
class Field extends React.Component {
handleChange = e => {
this.setValue(this.props.name, e.target.value);
};
handleBlur = () => {
this.setTouch(this.props.name, true);
};
setValue = (key, value) => {
const { formik } = this.context;
formik.setFieldValue(...update(key, value, formik.values));
};
setTouch = (key, value) => {
const { formik } = this.context;
formik.setFieldTouched(...update(key, value, formik.touched));
};
render() {
const { component = 'input', name, ...props } = this.props;
const value =
props.type === 'radio' || props.type === 'checkbox'
? props.value
: get(name, this.context.formik.values);
const field = {
value,
name,
onChange: this.handleChange,
onBlur: this.handleBlur
};
const bag =
typeof component === 'string'
? field
: {
field,
form: {
...this.context.formik,
handleChange: this.handleChange,
handleBlur: this.handleBlur,
setFieldValue: this.setValue,
setFieldTouched: this.setTouch
}
};
return React.createElement(component, {
...props,
...bag
});
}
}
Field.contextTypes = {
formik: PropTypes.object
};
export default Field;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment