|
1 | 1 | import React from 'react' |
2 | | -import { render, fireEvent } from '@testing-library/react' |
| 2 | +import { render, fireEvent, act } from '@testing-library/react' |
3 | 3 | import { Form, Field } from 'react-final-form' |
4 | 4 | import OnChange from './OnChange' |
5 | 5 |
|
@@ -158,4 +158,40 @@ describe('OnChange', () => { |
158 | 158 | expect(olivesCheckbox.checked).toBe(true) |
159 | 159 | expect(everythingCheckbox.checked).toBe(true) |
160 | 160 | }) |
| 161 | + |
| 162 | + it('should not call listener on re-renders when value has not changed (#7)', () => { |
| 163 | + // https://github.com/final-form/react-final-form-listeners/issues/7 |
| 164 | + // OnChange should NOT fire on re-renders when the value hasn't changed. |
| 165 | + const spy = jest.fn() |
| 166 | + let triggerRerender: () => void = () => {} |
| 167 | + |
| 168 | + const Parent = () => { |
| 169 | + const [count, setCount] = React.useState(0) |
| 170 | + triggerRerender = () => setCount(c => c + 1) |
| 171 | + return ( |
| 172 | + <Form onSubmit={onSubmitMock} initialValues={{ foo: 'bar' }}> |
| 173 | + {() => ( |
| 174 | + <div> |
| 175 | + <span data-testid="count">{count}</span> |
| 176 | + <Field name="foo" component="input" data-testid="foo" /> |
| 177 | + <OnChange name="foo">{spy}</OnChange> |
| 178 | + </div> |
| 179 | + )} |
| 180 | + </Form> |
| 181 | + ) |
| 182 | + } |
| 183 | + |
| 184 | + const { getByTestId } = render(<Parent />) |
| 185 | + |
| 186 | + // Spy might be called once on initial render (if value matches initial) |
| 187 | + const callsAfterMount = spy.mock.calls.length |
| 188 | + |
| 189 | + // Force re-renders without changing the field value |
| 190 | + act(() => { triggerRerender() }) |
| 191 | + act(() => { triggerRerender() }) |
| 192 | + act(() => { triggerRerender() }) |
| 193 | + |
| 194 | + // OnChange should not have been called due to re-renders alone |
| 195 | + expect(spy.mock.calls.length).toBe(callsAfterMount) |
| 196 | + }) |
161 | 197 | }) |
0 commit comments