diff --git a/package.json b/package.json index 8787e4a..e1694fc 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-transform-flow-strip-types": "^7.12.1", + "@babel/plugin-transform-react-jsx-source": "^7.18.6", "@babel/plugin-transform-runtime": "^7.12.1", "@babel/preset-env": "^7.12.1", "@babel/preset-flow": "^7.12.1", @@ -86,8 +87,8 @@ "peerDependencies": { "final-form": "^4.15.0", "final-form-arrays": ">=1.0.4", - "react-final-form": "^6.2.1", - "react": "^16.8.0 || ^17.0.0" + "react": "^16.8.0 || ^17.0.0", + "react-final-form": "^6.2.1" }, "jest": { "watchPlugins": [ diff --git a/src/FieldArray.test.js b/src/FieldArray.test.js index 9870b79..4cbe075 100644 --- a/src/FieldArray.test.js +++ b/src/FieldArray.test.js @@ -6,7 +6,7 @@ import { ErrorBoundary, Toggle, wrapWith } from './testUtils' import { Form, Field } from 'react-final-form' import { FieldArray, version } from '.' -const onSubmitMock = values => {} +const onSubmitMock = values => { } const timeout = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) async function sleep(ms) { await act(async () => { @@ -22,7 +22,7 @@ describe('FieldArray', () => { }) it('should warn if not used inside a form', () => { - jest.spyOn(console, 'error').mockImplementation(() => {}) + jest.spyOn(console, 'error').mockImplementation(() => { }) const errorSpy = jest.fn() render( @@ -38,7 +38,7 @@ describe('FieldArray', () => { }) it('should warn if no render strategy is provided', () => { - jest.spyOn(console, 'error').mockImplementation(() => {}) + jest.spyOn(console, 'error').mockImplementation(() => { }) const errorSpy = jest.fn() render( @@ -58,7 +58,7 @@ describe('FieldArray', () => { }) it('should warn if no array mutators provided', () => { - jest.spyOn(console, 'error').mockImplementation(() => {}) + jest.spyOn(console, 'error').mockImplementation(() => { }) const errorSpy = jest.fn() render( @@ -451,6 +451,58 @@ describe('FieldArray', () => { expect(queryByTestId('names[1]')).not.toBe(null) }) + it('should push a new value to right place after changing name', () => { + const { getByText, queryByTestId } = render( + + {isCats => ( +
+ {() => ( + + + {({ fields }) => ( +
+ {fields.map(field => ( + + ))} + +
+ )} +
+
+ )} + + )} +
+ ) + expect(queryByTestId('dogs[0]')).toBe(null) + expect(queryByTestId('dogs[1]')).toBe(null) + + // push + fireEvent.click(getByText('Add')) + + expect(queryByTestId('dogs[0]')).not.toBe(null) + expect(queryByTestId('dogs[1]')).toBe(null) + + // change name + fireEvent.click(getByText('Toggle')) + + expect(queryByTestId('cats[0]')).toBe(null) + expect(queryByTestId('cats[1]')).toBe(null) + + // push + fireEvent.click(getByText('Add')) + + expect(queryByTestId('cats[0]')).not.toBe(null) + expect(queryByTestId('cats[1]')).toBe(null) + }) + it('should not re-render Field when subscription is empty object', () => { const nameFieldRender = jest.fn() const surnameFieldRender = jest.fn() diff --git a/src/useFieldArray.js b/src/useFieldArray.js index d516b76..6cf256a 100644 --- a/src/useFieldArray.js +++ b/src/useFieldArray.js @@ -1,4 +1,5 @@ // @flow +import { useMemo } from 'react'; import { useForm, useField } from 'react-final-form' import { fieldSubscriptionItems, ARRAY_ERROR } from 'final-form' import type { Mutators } from 'final-form-arrays' @@ -31,13 +32,13 @@ const useFieldArray = ( 'Array mutators not found. You need to provide the mutators from final-form-arrays to your form' ) } - const mutators = useConstant(() => + const mutators = useMemo(() => // curry the field name onto all mutator calls Object.keys(formMutators).reduce((result, key) => { result[key] = (...args) => formMutators[key](name, ...args) return result - }, {}) - ) + }, {} + ), [name, formMutators]) const validate: FieldValidator = useConstant( () => (value, allValues, meta) => {