From f22eb8e99918663603ff150590465fe58be910b6 Mon Sep 17 00:00:00 2001 From: Evan Jacobs <570070+quantizor@users.noreply.github.com> Date: Wed, 10 Apr 2024 10:54:40 -0400 Subject: [PATCH 1/4] chore: update Evan's handle (#3965) --- .all-contributorsrc | 4 ++-- .github/CODEOWNERS | 6 +++--- .vscode/settings.json | 2 +- packages/formik/CHANGELOG.md | 28 ++++++++++++++-------------- packages/formik/package.json | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 03c818670..a5dd02a27 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -123,10 +123,10 @@ ] }, { - "login": "probablyup", + "login": "quantizor", "name": "Evan Jacobs", "avatar_url": "https://avatars.githubusercontent.com/u/570070?v=4", - "profile": "https://probablyup.com", + "profile": "https://quantizor.dev", "contributions": [ "question", "code", diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index b948465e4..605db9d96 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,6 @@ # Learn how to add code owners here: # https://help.github.com/en/articles/about-code-owners -* @jaredpalmer @probablyup -/docs/ @jaredpalmer @probablyup -/examples/ @jaredpalmer @probablyup \ No newline at end of file +* @jaredpalmer @quantizor +/docs/ @jaredpalmer @quantizor +/examples/ @jaredpalmer @quantizor \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index e56b4cfc8..11a40855a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,6 +2,6 @@ "typescript.tsdk": "node_modules/typescript/lib", "editor.formatOnSave": false, "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, } diff --git a/packages/formik/CHANGELOG.md b/packages/formik/CHANGELOG.md index a8cb976cd..cead81a0e 100644 --- a/packages/formik/CHANGELOG.md +++ b/packages/formik/CHANGELOG.md @@ -28,7 +28,7 @@ ### Patch Changes -- [`96280d3`](https://github.com/jaredpalmer/formik/commit/96280d388eaa0f2e9fb84e7fd2aa45450de3a949) [#3817](https://github.com/jaredpalmer/formik/pull/3817) Thanks [@probablyup](https://github.com/probablyup)! - Updated internal types to support React 18. +- [`96280d3`](https://github.com/jaredpalmer/formik/commit/96280d388eaa0f2e9fb84e7fd2aa45450de3a949) [#3817](https://github.com/jaredpalmer/formik/pull/3817) Thanks [@quantizor](https://github.com/quantizor)! - Updated internal types to support React 18. ## 2.4.1 @@ -36,21 +36,21 @@ - [`2b194c2`](https://github.com/jaredpalmer/formik/commit/2b194c287dc281ec2a8ff691d75c6b798ab5f70c) [#3808](https://github.com/jaredpalmer/formik/pull/3808) Thanks [@NagaiKoki](https://github.com/NagaiKoki)! - fix type of setFieldValue function -* [`708bcb2`](https://github.com/jaredpalmer/formik/commit/708bcb24785f1f8fbb5dfd649de3df4fddf7a113) [#3813](https://github.com/jaredpalmer/formik/pull/3813) Thanks [@probablyup](https://github.com/probablyup)! - Revert `FieldArray` "shouldComponentUpdate" performance optimization. As it turns out, it's a common use case to have JSX controlled via non-Formik state/props inside of `FieldArray`, so it's not safe to cancel re-renders here. +* [`708bcb2`](https://github.com/jaredpalmer/formik/commit/708bcb24785f1f8fbb5dfd649de3df4fddf7a113) [#3813](https://github.com/jaredpalmer/formik/pull/3813) Thanks [@quantizor](https://github.com/quantizor)! - Revert `FieldArray` "shouldComponentUpdate" performance optimization. As it turns out, it's a common use case to have JSX controlled via non-Formik state/props inside of `FieldArray`, so it's not safe to cancel re-renders here. -- [`187e47d`](https://github.com/jaredpalmer/formik/commit/187e47de0c4289cb279e25d69f8172cfa14369d2) [#3815](https://github.com/jaredpalmer/formik/pull/3815) Thanks [@probablyup](https://github.com/probablyup)! - Revert Yup transform support for the time being, this may be re-introduced in a future release under an opt-in prop. +- [`187e47d`](https://github.com/jaredpalmer/formik/commit/187e47de0c4289cb279e25d69f8172cfa14369d2) [#3815](https://github.com/jaredpalmer/formik/pull/3815) Thanks [@quantizor](https://github.com/quantizor)! - Revert Yup transform support for the time being, this may be re-introduced in a future release under an opt-in prop. ## 2.4.0 ### Minor Changes -- [`2f53b70`](https://github.com/jaredpalmer/formik/commit/2f53b70ef9c086a268330fa263390a2edd0164dd) [#3796](https://github.com/jaredpalmer/formik/pull/3796) Thanks [@probablyup](https://github.com/probablyup)! - Add support for Yup ["transforms"](https://github.com/jquense/yup#parsing-transforms). +- [`2f53b70`](https://github.com/jaredpalmer/formik/commit/2f53b70ef9c086a268330fa263390a2edd0164dd) [#3796](https://github.com/jaredpalmer/formik/pull/3796) Thanks [@quantizor](https://github.com/quantizor)! - Add support for Yup ["transforms"](https://github.com/jquense/yup#parsing-transforms). ## 2.3.3 ### Patch Changes -- [`f075a0c`](https://github.com/jaredpalmer/formik/commit/f075a0cf8228c135ff71c58e139246ad24aae529) [#3798](https://github.com/jaredpalmer/formik/pull/3798) Thanks [@probablyup](https://github.com/probablyup)! - Fixed the use of generics for the `ArrayHelpers` type such that `any[]` is the default array type and for each individual method the array item type can be overridden if necessary. +- [`f075a0c`](https://github.com/jaredpalmer/formik/commit/f075a0cf8228c135ff71c58e139246ad24aae529) [#3798](https://github.com/jaredpalmer/formik/pull/3798) Thanks [@quantizor](https://github.com/quantizor)! - Fixed the use of generics for the `ArrayHelpers` type such that `any[]` is the default array type and for each individual method the array item type can be overridden if necessary. ## 2.3.2 @@ -58,21 +58,21 @@ - [`f086b5a`](https://github.com/jaredpalmer/formik/commit/f086b5a3bb6a155b4dc4ac3735c88805f9f5c4e4) [#3237](https://github.com/jaredpalmer/formik/pull/3237) Thanks [@pieplu](https://github.com/pieplu)! - Changed `getIn` to return undefined when it can't find a value AND a parent of that value is "falsy" ( "" / 0 / null / false ) -* [`6d8f018`](https://github.com/jaredpalmer/formik/commit/6d8f018d7f52b863405b2e310be4b4195c2ba39c) [#3792](https://github.com/jaredpalmer/formik/pull/3792) Thanks [@probablyup](https://github.com/probablyup)! - Update the type for `setFieldValue` to reflect the returned `Promise` and potential returned error(s). +* [`6d8f018`](https://github.com/jaredpalmer/formik/commit/6d8f018d7f52b863405b2e310be4b4195c2ba39c) [#3792](https://github.com/jaredpalmer/formik/pull/3792) Thanks [@quantizor](https://github.com/quantizor)! - Update the type for `setFieldValue` to reflect the returned `Promise` and potential returned error(s). ## 2.3.1 ### Patch Changes -- [`290d92b`](https://github.com/jaredpalmer/formik/commit/290d92b34056593f551ad55baf00dc6f8c700bbe) [#3793](https://github.com/jaredpalmer/formik/pull/3793) Thanks [@probablyup](https://github.com/probablyup)! - Fix potential infinite loop scenario when `initialValues` changes but `enableReinitialize` is not truthy. +- [`290d92b`](https://github.com/jaredpalmer/formik/commit/290d92b34056593f551ad55baf00dc6f8c700bbe) [#3793](https://github.com/jaredpalmer/formik/pull/3793) Thanks [@quantizor](https://github.com/quantizor)! - Fix potential infinite loop scenario when `initialValues` changes but `enableReinitialize` is not truthy. ## 2.3.0 ### Minor Changes -- [`73de78d`](https://github.com/jaredpalmer/formik/commit/73de78d169f0bc25bd84dff0beaed3cc7a2cbb11) [#3788](https://github.com/jaredpalmer/formik/pull/3788) Thanks [@probablyup](https://github.com/probablyup)! - Added typescript generics to `ArrayHelpers` interface and its methods so that users who use TypeScript can set the type for their arrays and have type safety on array utils. I have also gone ahead and made supplying a type for the generic optional for the sake of backwards compatibility so any existing TS code that does not give a type for the FieldArray will continue to work as they always have. +- [`73de78d`](https://github.com/jaredpalmer/formik/commit/73de78d169f0bc25bd84dff0beaed3cc7a2cbb11) [#3788](https://github.com/jaredpalmer/formik/pull/3788) Thanks [@quantizor](https://github.com/quantizor)! - Added typescript generics to `ArrayHelpers` interface and its methods so that users who use TypeScript can set the type for their arrays and have type safety on array utils. I have also gone ahead and made supplying a type for the generic optional for the sake of backwards compatibility so any existing TS code that does not give a type for the FieldArray will continue to work as they always have. -* [`39a7bf7`](https://github.com/jaredpalmer/formik/commit/39a7bf7ca31f2ef5b149a8ff02bab64667e19654) [#3786](https://github.com/jaredpalmer/formik/pull/3786) Thanks [@probablyup](https://github.com/probablyup)! - Yup by default only allows for cross-field validation within the +* [`39a7bf7`](https://github.com/jaredpalmer/formik/commit/39a7bf7ca31f2ef5b149a8ff02bab64667e19654) [#3786](https://github.com/jaredpalmer/formik/pull/3786) Thanks [@quantizor](https://github.com/quantizor)! - Yup by default only allows for cross-field validation within the same field object. This is not that useful in most scenarios because a sufficiently-complex form will have several `yup.object()` in the schema. @@ -115,17 +115,17 @@ ### Patch Changes -- [`22e236e`](https://github.com/jaredpalmer/formik/commit/22e236ed8035c7c5824232202c8ce52193338d5a) [#3784](https://github.com/jaredpalmer/formik/pull/3784) Thanks [@probablyup](https://github.com/probablyup)! - Improve performance of the `FieldArray` component by adding a `shouldComponentUpdate` check; this should help avoid unnecessary re-renders which may affect the performance of a form. +- [`22e236e`](https://github.com/jaredpalmer/formik/commit/22e236ed8035c7c5824232202c8ce52193338d5a) [#3784](https://github.com/jaredpalmer/formik/pull/3784) Thanks [@quantizor](https://github.com/quantizor)! - Improve performance of the `FieldArray` component by adding a `shouldComponentUpdate` check; this should help avoid unnecessary re-renders which may affect the performance of a form. -* [`bc9cb28`](https://github.com/jaredpalmer/formik/commit/bc9cb28df7ad07277a499e8301cfd1bb7b230b86) [#3785](https://github.com/jaredpalmer/formik/pull/3785) Thanks [@probablyup](https://github.com/probablyup)! - Fixed field error state for array fields that have an error and become empty through an API like `arrayHelpers.remove`. +* [`bc9cb28`](https://github.com/jaredpalmer/formik/commit/bc9cb28df7ad07277a499e8301cfd1bb7b230b86) [#3785](https://github.com/jaredpalmer/formik/pull/3785) Thanks [@quantizor](https://github.com/quantizor)! - Fixed field error state for array fields that have an error and become empty through an API like `arrayHelpers.remove`. The prior behavior resolved the field error to `[undefined]`, now it is simply `undefined`. -- [`9cbf150`](https://github.com/jaredpalmer/formik/commit/9cbf150e65d7c5498900f19b4fa1897ca8a2c87f) [#3787](https://github.com/jaredpalmer/formik/pull/3787) Thanks [@probablyup](https://github.com/probablyup)! - Fix infinite loop issue in `Field` when field helpers (`setTouched`, etc) are used as an argument in `React.useEffect`. +- [`9cbf150`](https://github.com/jaredpalmer/formik/commit/9cbf150e65d7c5498900f19b4fa1897ca8a2c87f) [#3787](https://github.com/jaredpalmer/formik/pull/3787) Thanks [@quantizor](https://github.com/quantizor)! - Fix infinite loop issue in `Field` when field helpers (`setTouched`, etc) are used as an argument in `React.useEffect`. -* [`9c75a9f`](https://github.com/jaredpalmer/formik/commit/9c75a9f639eb38ad55c351e5e1def8a7e5ebd1f3) [#3780](https://github.com/jaredpalmer/formik/pull/3780) Thanks [@probablyup](https://github.com/probablyup)! - Fixed an issue with array field errors being incorrectly split into an array of individual characters instead of an array of error strings. +* [`9c75a9f`](https://github.com/jaredpalmer/formik/commit/9c75a9f639eb38ad55c351e5e1def8a7e5ebd1f3) [#3780](https://github.com/jaredpalmer/formik/pull/3780) Thanks [@quantizor](https://github.com/quantizor)! - Fixed an issue with array field errors being incorrectly split into an array of individual characters instead of an array of error strings. -- [`35fa4cc`](https://github.com/jaredpalmer/formik/commit/35fa4cc38260d709a5570dd3c9ef82831758a5f5) [#3783](https://github.com/jaredpalmer/formik/pull/3783) Thanks [@probablyup](https://github.com/probablyup)! - Fix validation of deep.dot.path field references when using the `validateField` API. +- [`35fa4cc`](https://github.com/jaredpalmer/formik/commit/35fa4cc38260d709a5570dd3c9ef82831758a5f5) [#3783](https://github.com/jaredpalmer/formik/pull/3783) Thanks [@quantizor](https://github.com/quantizor)! - Fix validation of deep.dot.path field references when using the `validateField` API. ## 2.2.9 diff --git a/packages/formik/package.json b/packages/formik/package.json index 2db8b4ac9..c8e830ab0 100644 --- a/packages/formik/package.json +++ b/packages/formik/package.json @@ -5,7 +5,7 @@ "license": "Apache-2.0", "author": "Jared Palmer (https://jaredpalmer.com)", "contributors": [ - "Evan Jacobs (https://probablyup.com)" + "Evan Jacobs (https://quantizor.dev)" ], "repository": "jaredpalmer/formik", "homepage": "https://formik.org", From ba15818e7d2c97bbed074b45cb80baac1b38aa01 Mon Sep 17 00:00:00 2001 From: Tex Andersen Date: Thu, 11 Apr 2024 01:01:22 +1000 Subject: [PATCH 2/4] Fix broken code example in FastField API docs + update CONTRIBUTING.md `master` references to `main` (#3958) Title pretty much summarises it. --- .github/CONTRIBUTING.md | 6 +++--- docs/api/fastfield.md | 11 ++++++----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index b58951398..1193bd4d0 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -69,8 +69,8 @@ git remote add upstream https://github.com/formik/formik.git 3. Synchronize your local `next` branch with the upstream one: ```sh -git checkout master -git pull upstream master +git checkout main +git pull upstream main ``` 4. Install the dependencies with [yarn](https://yarnpkg.com) (npm isn't supported): @@ -122,7 +122,7 @@ the results. If any of them fail, refer to [Checks and how to fix them](#checks- Make sure the following is true: -- The branch is targeted at `master` for ongoing development. We do our best to keep `master` in good shape, with all tests passing. Code that lands in `master` must be compatible with the latest stable release. It may contain additional features, but no breaking changes. We should be able to release a new minor version from the tip of `master` at any time. +- The branch is targeted at `main` for ongoing development. We do our best to keep `main` in good shape, with all tests passing. Code that lands in `main` must be compatible with the latest stable release. It may contain additional features, but no breaking changes. We should be able to release a new minor version from the tip of `main` at any time. - If a feature is being added: - If the result was already achievable with the library, explain why this feature needs to be added. - If this is a common use case, consider adding an example to the documentation. diff --git a/docs/api/fastfield.md b/docs/api/fastfield.md index cd9d7b1bf..32fa48ee3 100644 --- a/docs/api/fastfield.md +++ b/docs/api/fastfield.md @@ -57,7 +57,8 @@ const Basic = () => ( alert(JSON.stringify(values, null, 2)); }, 500); }} - render={formikProps => ( + > + {formikProps => (
{/** This only updates for changes made to values.firstName, touched.firstName, errors.firstName */} @@ -66,8 +67,8 @@ const Basic = () => ( {/** Updates for all changes because it's from the top-level formikProps which get all updates */} - {form.touched.firstName && form.errors.firstName && ( -
{form.errors.firstName}
+ {formikProps.touched.firstName && formikProps.errors.firstName && ( +
{formikProps.errors.firstName}
)} @@ -105,7 +106,7 @@ const Basic = () => ( and all changes by all s and s */} - {() => ( + {({ field, form, meta }) => (
{/** Works because this is inside @@ -125,7 +126,7 @@ const Basic = () => ( )} - /> +
); ``` From c6ceb654761c268fdc76b225f31453dd4dec1be6 Mon Sep 17 00:00:00 2001 From: Bailey Lissington <54869395+llamington@users.noreply.github.com> Date: Thu, 11 Apr 2024 03:02:21 +1200 Subject: [PATCH 3/4] Fix grammatical error in field.md (#3928) --- docs/api/field.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/field.md b/docs/api/field.md index 422493ec6..a2c1002c6 100644 --- a/docs/api/field.md +++ b/docs/api/field.md @@ -102,7 +102,7 @@ Either a React component or the name of an HTML element to render. That is, one - A valid HTML element name - A custom React component -Custom React components will be passed `onChange`, `onBlur`, `name`, and `value` plus any other props passed to directly to ``. +Custom React components will be passed `onChange`, `onBlur`, `name`, and `value` plus any other props passed directly to ``. Default is `'input'` (so an `` is rendered by default) From f57ca9bc5ee3842d50f74f39b3fb36a744b55ae8 Mon Sep 17 00:00:00 2001 From: DeveloperRaj <40798951+DeveloperRaj@users.noreply.github.com> Date: Thu, 11 Apr 2024 00:16:56 +0530 Subject: [PATCH 4/4] Fix #3948 - Changing state was also causing change of initial value (#3949) Resolves Issue #3948 This addresses the problem of the dirty field not updating when the value of a nested object changes. The root cause of this issue is that the `initialValues` coming from props were directly assigned to the `useRef`, which did not perform a deep copy. Without a deep copy, it was modifying the original `initialValues` props along with the current state. Consequently, when comparing them for equality, the result was true --- .changeset/empty-vans-bathe.md | 5 ++++ packages/formik/src/Formik.tsx | 9 +++--- packages/formik/test/Formik.test.tsx | 44 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 .changeset/empty-vans-bathe.md diff --git a/.changeset/empty-vans-bathe.md b/.changeset/empty-vans-bathe.md new file mode 100644 index 000000000..adfff99c5 --- /dev/null +++ b/.changeset/empty-vans-bathe.md @@ -0,0 +1,5 @@ +--- +'formik': patch +--- + +Changing the state inside formik was changing reference of initialValues provided via props, deep cloning the initialvalues will fix it. diff --git a/packages/formik/src/Formik.tsx b/packages/formik/src/Formik.tsx index cd17adcd4..80d868665 100755 --- a/packages/formik/src/Formik.tsx +++ b/packages/formik/src/Formik.tsx @@ -1,5 +1,6 @@ import deepmerge from 'deepmerge'; import isPlainObject from 'lodash/isPlainObject'; +import cloneDeep from 'lodash/cloneDeep'; import * as React from 'react'; import isEqual from 'react-fast-compare'; import invariant from 'tiny-warning'; @@ -173,10 +174,10 @@ export function useFormik({ const [, setIteration] = React.useState(0); const stateRef = React.useRef>({ - values: props.initialValues, - errors: props.initialErrors || emptyErrors, - touched: props.initialTouched || emptyTouched, - status: props.initialStatus, + values: cloneDeep(props.initialValues), + errors: cloneDeep(props.initialErrors) || emptyErrors, + touched: cloneDeep(props.initialTouched) || emptyTouched, + status: cloneDeep(props.initialStatus), isSubmitting: false, isValidating: false, submitCount: 0, diff --git a/packages/formik/test/Formik.test.tsx b/packages/formik/test/Formik.test.tsx index 2acf332dd..98b6ef3c9 100644 --- a/packages/formik/test/Formik.test.tsx +++ b/packages/formik/test/Formik.test.tsx @@ -61,6 +61,20 @@ const InitialValues = { age: 30, }; +const InitialValuesWithNestedObject = { + content: { + items: [ + { + cards: [ + { + desc: 'Initial Desc', + }, + ], + }, + ], + }, +}; + function renderFormik( props?: Partial> ) { @@ -1454,4 +1468,34 @@ describe('', () => { expect(innerRef.current).toEqual(getProps()); }); + + it('should not modify original initialValues object', () => { + render( + + {formikProps => ( + { + const copy = { ...formikProps.values.content }; + copy.items[0].cards[0].desc = e.target.value; + formikProps.setValues({ + ...formikProps.values, + content: copy, + }); + }} + /> + )} + + ); + const input = screen.getByTestId('desc-input'); + + fireEvent.change(input, { + target: { + value: 'New Value', + }, + }); + + expect(InitialValuesWithNestedObject.content.items[0].cards[0].desc).toEqual('Initial Desc'); + }); });