ton1
ton1

Reputation: 7628

How to use custom Input with Formik in React?

I'm trying to use DatePicker within Formik. But when I click DatePicker's date its form value is not changed. Instead, I got this error:

Uncaught TypeError: e.persist is not a function at Formik._this.handleChange (formik.es6.js:5960)

I shortify code, the code is below

const SomeComponent = () => (
    <Formik
        render={({
            values,
            handleSubmit,
            handleChange,
            setFieldValue
        }) => {
            return (
                <div>
                    <form onSubmit={handleSubmit}>
                        <DatePicker
                            name={'joinedAt'}
                            value={values['joinedAt']}
                            onChange={handleChange}
                        />
                    </form>
                </div>
            )
        }}
    />
)

I googled few documents, https://github.com/jaredpalmer/formik/issues/187 and https://github.com/jaredpalmer/formik/issues/86

So I tried like below, but it's not working.

 ...setFieldValue

 <DatePicker
   name={'joinedAt'}
   value={values['joinedAt']}
   onChange={setFieldValue}
 />

Upvotes: 51

Views: 79036

Answers (6)

Jaryt
Jaryt

Reputation: 21

The Formik solution for this is the useField() method. You may need to create a wrapper for components like DatePicker that you may not have source access to.

The documentation provides an example:

const MyTextField = ({ label, ...props }) => {
   const [field, meta, helpers] = useField(props);
   return (
     <>
       <label>
         {label}
         <input {...field} {...props} />
       </label>
       {meta.touched && meta.error ? (
         <div className="error">{meta.error}</div>
       ) : null}
     </>
   );
 };

In short, the method takes in the custom props which describe the field. Then you can expand the assigned field value and props in your custom field.

Upvotes: 2

ton1
ton1

Reputation: 7628

I resolve this like

<DatePicker
   name={'joinedAt'}
   value={values['joinedAt']}
   onChange={e => setFieldValue('joinedAt', e)}
/>

Update on 2020-03-08:

You can use e.target.value on setFieldValue's second prop, depends on your custom input design. Thanks to Brandon.

Upvotes: 73

Hugo Gresse
Hugo Gresse

Reputation: 17899

If you have deeper nesting, you should use Formik Field. Example:


<Formik
    validationSchema={schema}
    initialValues={initialValues}
    onSubmit={(values, actions) => {}}
>

  <Field name="colors" component={ColorsEditor}  colors={colorArray}/>
</Formik>


const ColorsEditor = ({ field, colors, form, ...props }) => {

    return (
        <div>
            <Button onClick={() => form.setFieldValue('colors', "myValue")}>
            </Button>
        </div>
    )
}

So the Field component already include the form, where live the setFieldValue that you can use where you need. It also include the errors and needed fields for additional customization.

Upvotes: 14

brijmcq
brijmcq

Reputation: 3418

The accepted answer didn't work for me and didn't show the selected date. It has been almost a year so there might be some changes with the implementation. Though this can be fix by using toDateString() like this

<DatePicker
   name={'joinedAt'}
   value={values['joinedAt']}
   onChange={e => setFieldValue('joinedAt', e.toDateString())}
 />

Upvotes: 3

Imdadul Huq Naim
Imdadul Huq Naim

Reputation: 364

For html primitive input fields handleChange works like a charm, but for custom components, you've to use setFieldValue to change the value imperatively.

onChange={e => setFieldValue('joinedAt', e)}

Upvotes: 3

Varis Bhalala
Varis Bhalala

Reputation: 201

https://github.com/jaredpalmer/formik/issues/692

you need to set value manually if you are using setFieldValue method

Upvotes: 0

Related Questions