Skip to content

Commit 638d825

Browse files
jdimovskaerikras
authored andcommitted
Fixed FieldArray re-render on every change when subscription is empty object (#100)
1 parent 4fd4e5c commit 638d825

File tree

3 files changed

+64
-5
lines changed

3 files changed

+64
-5
lines changed

src/FieldArray.test.js

+58-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react'
22
import { render, fireEvent, cleanup } from '@testing-library/react'
33
import '@testing-library/jest-dom/extend-expect'
44
import arrayMutators from 'final-form-arrays'
5-
import { ErrorBoundary, Toggle } from './testUtils'
5+
import { ErrorBoundary, Toggle, wrapWith } from './testUtils'
66
import { Form, Field } from 'react-final-form'
77
import { FieldArray, version } from '.'
88

@@ -129,7 +129,7 @@ describe('FieldArray', () => {
129129
const renderArray = jest.fn(() => <div />)
130130
class Container extends React.Component {
131131
state = { name: 'dogs' }
132-
132+
133133
render() {
134134
return (
135135
<form>
@@ -149,10 +149,10 @@ describe('FieldArray', () => {
149149
expect(renderArray).toHaveBeenCalled()
150150
expect(renderArray).toHaveBeenCalledTimes(1)
151151
expect(renderArray.mock.calls[0][0].value).toBeUndefined()
152-
152+
153153
const button = TestUtils.findRenderedDOMComponentWithTag(dom, 'button')
154154
TestUtils.Simulate.click(button)
155-
155+
156156
expect(renderArray).toHaveBeenCalledTimes(2)
157157
expect(renderArray.mock.calls[1][0].value).toBeUndefined()
158158
})
@@ -445,6 +445,60 @@ describe('FieldArray', () => {
445445
expect(queryByTestId('names[1]')).not.toBe(null)
446446
})
447447

448+
it('should not re-render Field when subscription is empty object', () => {
449+
const nameFieldRender = jest.fn()
450+
const surnameFieldRender = jest.fn()
451+
452+
const { getByTestId } = render(
453+
<Form
454+
onSubmit={onSubmitMock}
455+
mutators={arrayMutators}
456+
subscription={{}}
457+
initialValues={{
458+
names: [{ id: 1, name: 'John', surname: 'Doe' }]
459+
}}
460+
>
461+
{({ handleSubmit }) => (
462+
<form onSubmit={handleSubmit} data-testid="form">
463+
<FieldArray name="names" subscription={{}}>
464+
{({ fields }) =>
465+
fields.map(field => {
466+
return (
467+
<div key={`${field}.id`}>
468+
<Field name={`${field}.name`}>
469+
{wrapWith(nameFieldRender, ({ input }) => (
470+
<input data-testid={`${field}.name`} {...input} />
471+
))}
472+
</Field>
473+
<Field name={`${field}.surname`}>
474+
{wrapWith(surnameFieldRender, ({ input }) => (
475+
<input data-testid={`${field}.surname`} {...input} />
476+
))}
477+
</Field>
478+
</div>
479+
)
480+
})
481+
}
482+
</FieldArray>
483+
</form>
484+
)}
485+
</Form>
486+
)
487+
488+
fireEvent.change(getByTestId('names[0].name'), {
489+
target: { value: 'Sue' }
490+
})
491+
expect(getByTestId('names[0].name').value).toBe('Sue')
492+
493+
fireEvent.change(getByTestId('names[0].name'), {
494+
target: { value: 'Paul' }
495+
})
496+
expect(getByTestId('names[0].name').value).toBe('Paul')
497+
498+
expect(nameFieldRender).toHaveBeenCalledTimes(3)
499+
expect(surnameFieldRender).toHaveBeenCalledTimes(1)
500+
})
501+
448502
it('should allow Fields to be rendered for complex objects', () => {
449503
const onSubmit = jest.fn()
450504
const { getByTestId, getByText, queryByTestId } = render(

src/testUtils.js

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import React from 'react'
22

3+
export const wrapWith = (mock, fn) => (...args) => {
4+
mock(...args)
5+
return fn(...args)
6+
}
7+
38
/** A simple container component that allows boolean to be toggled with a button */
49
export function Toggle({ children }) {
510
const [on, setOn] = React.useState(false)

src/useFieldArray.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const useFieldArray = (
5757
input,
5858
...fieldState
5959
} = useField(name, {
60-
subscription: { ...subscription, value: true, length: true },
60+
subscription: { ...subscription, length: true },
6161
isEqual,
6262
validate,
6363
format: v => v

0 commit comments

Comments
 (0)