Formik: Support custom input components

Created on 24 Jul 2017  路  6Comments  路  Source: formium/formik

It would be really great to support custom components, eg. custom inputs, datepickers, timepickers, etc.
As an option, a curried version of handleChange can be created, smth like handleChangeFor, so the usage could look as follows

Formik({
  mapPropsToValues: props => ({
    date: props.user.birthdate
  })
})(({handleChangeFor}) => (
  /// ...
  <SomeDatePicker
    onChange={handleChangeFor('date')}>
  // ...
));

I know this can be done using setFieldValue, but such utility function will help a lot.
Avoiding imperative onChange={value => setFieldValue('date', value)} would be awesome.
Here's a sample implementation :wink:

handleChangeFor (field) {
  return value => setFieldValue(field, value);
}

Would appreciate hearing your thoughts on this

Most helpful comment

If anyone is curious, I ended up with hoc on top of Formik, smth like:

import {Formik} from 'formik';
import {compose, withProps} from 'recompact';

const withFormik = options => compose(
  Formik(options),
  withProps(({setFieldValue, setFieldTouched}) => ({
    handleChangeFor: field => ({value}) => {
      setFieldValue(field, value);
    },
    handleBlurFor: field => () => {
      setFieldTouched(field, true);
    }
  }))
);

export default withFormik;

Considering all your "custom" inputs trigger onChange or similar, with {value} as an argument.

All 6 comments

Also, you can still use handleChange and handleBlur as long as your custom input results in a value and accepts and id or name

@jaredpalmer thanks for pointing that out.
Although having such utility function, kind of curried version of setFieldValue, will help to reduce amount of boilerplate imperative code while working with both Custom Components and React Native, where handler argument shape is different from {persist, target: {name, id, type, value}}

If anyone is curious, I ended up with hoc on top of Formik, smth like:

import {Formik} from 'formik';
import {compose, withProps} from 'recompact';

const withFormik = options => compose(
  Formik(options),
  withProps(({setFieldValue, setFieldTouched}) => ({
    handleChangeFor: field => ({value}) => {
      setFieldValue(field, value);
    },
    handleBlurFor: field => () => {
      setFieldTouched(field, true);
    }
  }))
);

export default withFormik;

Considering all your "custom" inputs trigger onChange or similar, with {value} as an argument.

Hi, @jaredpalmer that link (https://github.com/jaredpalmer/formik#avoiding-a-render-callback) doesn't work anymore. Does relevant documentation still exist? I'm rendering a custom text field component in React Native and trying to figure out how to prevent a re-render when text changes.

Thank you!

@eugene-kim I think the link has changed to https://github.com/jaredpalmer/formik#avoiding-new-functions-in-render - the heading in the README was changed, but the content of the paragraph is still the relevant bit you need.

/edit: relevant commit that changed the heading: https://github.com/jaredpalmer/formik/commit/ceb56399cf30c96fa9863a67df1e7dcaced746e4

Was this page helpful?
0 / 5 - 0 ratings