Build forms in React, without the tears 😭
APACHE-2.0 License
Bot releases are hidden (Show)
shouldComponentUpdate
by refactoring the component away from using static contextType
and back to using the connect()
higher order component.Fixed regression where dirty
is wasn't re-evaluated after resetForm()
Fixed regression where handleChange would explode when event.target didn't exist (e.g. event.currentTarget
If there are validation errors while calling submitForm()
, the promise will now rejects with errors (and of course abort the submit). Previously, it would abort the submit and resolve. The nuance is hard to describe so here is the difference.
Before (2.0.6)
submitForm() // imagine there are some Yup validation errors
.then(() => console.log("abort submit, did not call onSubmit, and end up here"))
.catch(() => console.log("abort submit, did not call onSubmit, but only because of a runtime error"));
After (2.0.7)
submitForm() // imagine there are some Yup validation errors
.then(() => console.log("executed onSubmit"))
.catch((err) => console.log("aborted submit attempt"));
2.0.6: https://codesandbox.io/s/gracious-noether-bu8u6
2.0.7: https://codesandbox.io/s/objective-perlman-jxhuq
Commits
https://github.com/jaredpalmer/formik/compare/v2.0.6...v2.0.7
Promise<any>
. This allows folks to return a promise that returns something (which is pretty common). Sorry about that folks.Commits
https://github.com/jaredpalmer/formik/compare/v2.0.5...v2.0.6
onSubmit
behavior to mimic v1 if the function is synchronous. This means fixes a bug where isSubmitting
was never toggled. To summarize: If onSubmit
is async, then Formik will automatically set isSubmitting
to false
on your behalf once the submission is completed. This means you do NOT need to call formikBag.setSubmitting(false)
manually in v2. HOWEVER, if your onSubmit
function is synchronous (e.g. v1), then you need to still call setSubmitting(false)
on your own. (#1987)validateFormWithLowPriority
with to use fresh values (#2025)Commits
isSubmitting
behaviour to mimic v1 (#1987) 3ce6551https://github.com/jaredpalmer/formik/compare/v2.0.4...v2.0.5
prepareDataForValidation
work with instances (#1949) ec7810a. this fixed a regression where people were having issues when keeping wonky objects like Moment()
as values.scheduler
dep.Commits
FormikActions
rename to FormikHelpers
(#1988) f80d9c6.min()
method to max()
(#1959) 654b97fhttps://github.com/jaredpalmer/formik/compare/v2.0.3...v2.0.4
<Form>
due to omitted 2nd generic to React.forwardRef
. TypeScript users should use this version.Commits
https://github.com/jaredpalmer/formik/compare/v2.0.2...v2.0.3
useField
so that it returns a tupleCommits
https://github.com/jaredpalmer/formik/compare/v2.0.1...v2.0.2
unknown
type, you must be on TypeScript 3.0 or higherresetForm
There is only one tiny breaking change in Formik 2.x. Luckily, it probably won't impact verry many people. Long story short, because we introduced initialErrors
, initialTouched
, initialStatus
props, resetForm
's signature has changed. It now accepts the next initial state of Formik (instead of just the next initial values).
v1
resetForm(nextValues);
v2
resetForm({ values: nextValues /* errors, touched, etc ... */ });
Similarly to Angular, Vue, or Svelte, Formik 2 "fixes" React checkboxes and multi-selects with built-in array binding and boolean behavior. This was one of the most confusing things for people in Formik 1.x.
import React from 'react';
import { Formik, Field, Form } from 'formik';
import { Debug } from './Debug';
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const CheckboxExample = () => (
<div>
<h1>Checkboxes</h1>
<p>
This example demonstrates how to properly create checkboxes with Formik.
</p>
<Formik
initialValues={{
isAwesome: false,
terms: false,
newsletter: false,
jobType: ['designer'],
location: [],
}}
onSubmit={async values => {
await sleep(1000);
alert(JSON.stringify(values, null, 2));
}}
>
{({ isSubmitting, getFieldProps, handleChange, handleBlur, values }) => (
<Form>
{/*
This first checkbox will result in a boolean value being stored.
*/}
<div className="label">Basic Info</div>
<label>
<Field type="checkbox" name="isAwesome" />
Are you awesome?
</label>
{/*
Multiple checkboxes with the same name attribute, but different
value attributes will be considered a "checkbox group". Formik will automagically
bind the checked values to a single array for your benefit. All the add and remove
logic will be taken care of for you.
*/}
<div className="label">
What best describes you? (check all that apply)
</div>
<label>
<Field type="checkbox" name="jobType" value="designer" />
Designer
</label>
<label>
<Field type="checkbox" name="jobType" value="developer" />
Developer
</label>
<label>
<Field type="checkbox" name="jobType" value="product" />
Product Manager
</label>
{/*
You do not _need_ to use <Field>/useField to get this behaviorr,
using handleChange, handleBlur, and values works as well.
*/}
<label>
<input
type="checkbox"
name="jobType"
value="founder"
checked={values.jobType.includes('founder')}
onChange={handleChange}
onBlur={handleBlur}
/>
CEO / Founder
</label>
{/*
The <select> element will also behave the same way if
you pass `multiple` prop to it.
*/}
<label htmlFor="location">Where do you work?</label>
<Field
component="select"
id="location"
name="location"
multiple={true}
>
<option value="NY">New York</option>
<option value="SF">San Francisco</option>
<option value="CH">Chicago</option>
<option value="OTHER">Other</option>
</Field>
<label>
<Field type="checkbox" name="terms" />I accept the terms and
conditions.
</label>
{/* Here's how you can use a checkbox to show / hide another field */}
{!!values.terms ? (
<div>
<label>
<Field type="checkbox" name="newsletter" />
Send me the newsletter <em style={{ color: 'rebeccapurple' }}>
(This is only shown if terms = true)
</em>
</label>
</div>
) : null}
<button type="submit" disabled={isSubmitting}>
Submit
</button>
<Debug />
</Form>
)}
</Formik>
</div>
);
export default CheckboxExample;
useField()
Just what you think, it's like <Field>
, but with a hook. See docs for usage.
useFormikContext()
A hook that is equivalent to connect()
.
<Field as>
<Field/>
now accepts a prop called as
which will inject onChange
, onBlur
, value
etc. directly through to the component or string. This is useful for folks using Emotion or Styled components as they no longer need to clean up component
's render props in a wrapped function.
FormikContext
is now exportedvalidateOnMount?: boolean = false
initialErrors
, initialTouched
, initialStatus
have been added// <input className="form-input" placeHolder="Jane" />
<Field name="firstName" className="form-input" placeholder="Jane" />
// <textarea className="form-textarea"/></textarea>
<Field name="message" as="textarea" className="form-input"/>
// <select className="my-select"/>
<Field name="colors" as="select" className="my-select">
<option value="red">Red</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
</Field>
// with styled-components/emotion
const MyStyledInput = styled.input`
padding: .5em;
border: 1px solid #eee;
/* ... */
`
const MyStyledTextarea = MyStyledInput.withComponent('textarea');
// <input className="czx_123" placeHolder="google.com" />
<Field name="website" as={MyStyledInput} placeHolder="google.com"/>
// <textarea placeHolder="Post a message..." rows={5}></textarea>
<Field name="message" as={MyStyledTextArea} placeHolder="Post a message.." rows={4}/>
getFieldProps(nameOrProps)
There are two useful additions to FormikProps
, getFieldProps
and getFieldMeta
. These are Kent C. Dodds-esque prop getters that can be useful if you love prop drilling, are not using the context-based API's, or if you are building a custom useField
.
export interface FieldInputProps<Value> {
/** Value of the field */
value: Value;
/** Name of the field */
name: string;
/** Multiple select? */
multiple?: boolean;
/** Is the field checked? */
checked?: boolean;
/** Change event handler */
onChange: FormikHandlers['handleChange'];
/** Blur event handler */
onBlur: FormikHandlers['handleBlur'];
}
getFieldMeta(name)
Given a name it will return an object:
export interface FieldMetaProps<Value> {
/** Value of the field */
value: Value;
/** Error message of the field */
error?: string;
/** Has the field been visited? */
touched: boolean;
/** Initial value of the field */
initialValue?: Value;
/** Initial touched state of the field */
initialTouched: boolean;
/** Initial error message of the field */
initialError?: string;
}
render
props have been deprecated with a console warning.For <Field>
, <FastField>
, <Formik>
,<FieldArray>
, the render
prop has been deprecated with a warning as it will be removed in future versions. Instead, use a child callback function. This deprecation is meant to parallel React Context Consumer's usage.
- <Field name="firstName" render={props => ....} />
+ <Field name="firstName">{props => ... }</Field>
<Form>
uses React.forwardRef
now<FastField />
is back. It's slightly fast now since it uses contextType
instead of the connect
HoC.FormikContext
is exportedarray.splice is not a function
errors when using array-like item in FieldArrayDeprecate (#1917) 9107225
Undeprecate (#1915) c289eb1
getFieldProps
now only returns FieldInputProps
instead of [FieldInputProps, FieldMetaProps]
. This makes is more useful to folks using it with just useFormik
getFieldMeta(name: string)
has been added to formik bag. This lets you get this object back for a given field.
export interface FieldMetaProps<Value> {
/** Value of the field */
value: Value;
/** Error message of the field */
error?: string;
/** Has the field been visited? */
touched: boolean;
/** Initial value of the field */
initialValue?: Value;
/** Initial touched state of the field */
initialTouched: boolean;
/** Initial error message of the field */
initialError?: string;
}
Commits
array.splice is not a function
errors when using array-li… (#1830) d972008https://github.com/jaredpalmer/formik/compare/v2.0.1-rc.14...v2.0.1-rc.15
validateOnMount?: boolean = false
(does what you think it does)initialX
.Commits
https://github.com/jaredpalmer/formik/compare/v2.0.1-rc.13...v2.0.1-rc.14
useField()
. This means that you can now pass useField()
a field-level validation function.
const [field, meta] = useField({ name: 'boop', validate: (value) => ({ /* ... */ }) })
Cannot call an event handler while rendering despite using React.useEffect
(#1763)Commits
yarn add yup
(#1687) 217a49eField
s with Form
(#1681) c63b1cfhttps://github.com/jaredpalmer/formik/compare/v2.0.1-rc.12...v2.0.1-rc.13
Commits
https://github.com/jaredpalmer/formik/compare/v1.5.7...v1.5.8
lodash
Vulnerable versions: < 4.6.2
Patched version: 4.6.2
Affected versions of lodash are vulnerable to Prototype Pollution. The function defaultsDeep could be tricked into adding or modifying properties of Object.prototype using a constructor payload.
Commits
https://github.com/jaredpalmer/formik/compare/v2.0.1-rc.11...v2.0.1-rc.12
Yup.validateAt
behavior in added rc.10 as it caused untenable issues with isValid
behavior. (#1654)Commits
https://github.com/jaredpalmer/formik/compare/v2.0.1-rc.10...v2.0.1-rc.11
Schema based low-priority validation (triggered by change/blur) now runs at a given schema path using Yup.schema.validateAt
(if possible). This means that Yup will run validation against a single slice of the whole schema if it can do so. This should significantly boost perf on underpowered devices. There may be some edge cases that we need to iron out, but neither I or Jason Quense could come up with ones. Regardless, we'll mark this as a breaking change (even though it probably isn't).
Commits
https://github.com/jaredpalmer/formik/compare/v2.0.1-rc.8...v2.0.1-rc.10
Commits
https://github.com/jaredpalmer/formik/compare/v2.0.1-rc.7...v2.0.1-rc.8
tsdx
to 0.7.x (our ESM module build is no longer minified)FormikErrors
supports array typesCommits
https://github.com/jaredpalmer/formik/compare/v2.0.1-rc.6...v2.0.1-rc.7
Before
Calling resetForm
without passing a full state object yielded this TS error:
Type '{ values: { email: string; }; }' is missing the following properties from type 'FormikState<{ email: string; }>': errors, touched, isSubmitting, isValidating, submitCount TS2345
After
No TS error when passing partial state object to resetForm
Commits
https://github.com/jaredpalmer/formik/compare/v2.0.1-rc.5...v2.0.1-rc.6