Skip to content

Commit 28c0815

Browse files
authored
fix: Should force re render when shouldUpdate is true (#117)
* test first * force re-render
1 parent 6895ebe commit 28c0815

File tree

2 files changed

+69
-32
lines changed

2 files changed

+69
-32
lines changed

src/Field.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,15 @@ class Field extends React.Component<InternalFieldProps, FieldState> implements F
114114

115115
// ============================== Subscriptions ==============================
116116
public componentDidMount() {
117+
const { shouldUpdate } = this.props;
117118
const { getInternalHooks }: InternalFormInstance = this.context;
118119
const { registerField } = getInternalHooks(HOOK_MARK);
119120
this.cancelRegisterFunc = registerField(this);
121+
122+
// One more render for component in case fields not ready
123+
if (shouldUpdate === true) {
124+
this.reRender();
125+
}
120126
}
121127

122128
public componentWillUnmount() {

tests/index.test.js

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -311,44 +311,75 @@ describe('Form.Basic', () => {
311311
expect(wrapper.find('.anything').props().light).toEqual('bamboo');
312312
});
313313

314-
it('shouldUpdate', async () => {
315-
let isAllTouched;
316-
let hasError;
314+
describe('shouldUpdate', () => {
315+
it('work', async () => {
316+
let isAllTouched;
317+
let hasError;
317318

318-
const wrapper = mount(
319-
<Form>
320-
<Field name="username" rules={[{ required: true }]}>
321-
<Input />
322-
</Field>
323-
<Field name="password" rules={[{ required: true }]}>
324-
<Input />
325-
</Field>
326-
<Field shouldUpdate>
327-
{(_, __, { getFieldsError, isFieldsTouched }) => {
328-
isAllTouched = isFieldsTouched(true);
329-
hasError = getFieldsError().filter(({ errors }) => errors.length).length;
319+
const wrapper = mount(
320+
<Form>
321+
<Field name="username" rules={[{ required: true }]}>
322+
<Input />
323+
</Field>
324+
<Field name="password" rules={[{ required: true }]}>
325+
<Input />
326+
</Field>
327+
<Field shouldUpdate>
328+
{(_, __, { getFieldsError, isFieldsTouched }) => {
329+
isAllTouched = isFieldsTouched(true);
330+
hasError = getFieldsError().filter(({ errors }) => errors.length).length;
330331

331-
return null;
332-
}}
333-
</Field>
334-
</Form>,
335-
);
332+
return null;
333+
}}
334+
</Field>
335+
</Form>,
336+
);
337+
338+
await changeValue(getField(wrapper, 'username'), '');
339+
expect(isAllTouched).toBeFalsy();
340+
expect(hasError).toBeTruthy();
336341

337-
await changeValue(getField(wrapper, 'username'), '');
338-
expect(isAllTouched).toBeFalsy();
339-
expect(hasError).toBeTruthy();
342+
await changeValue(getField(wrapper, 'username'), 'Bamboo');
343+
expect(isAllTouched).toBeFalsy();
344+
expect(hasError).toBeFalsy();
345+
346+
await changeValue(getField(wrapper, 'password'), 'Light');
347+
expect(isAllTouched).toBeTruthy();
348+
expect(hasError).toBeFalsy();
349+
350+
await changeValue(getField(wrapper, 'password'), '');
351+
expect(isAllTouched).toBeTruthy();
352+
expect(hasError).toBeTruthy();
353+
});
340354

341-
await changeValue(getField(wrapper, 'username'), 'Bamboo');
342-
expect(isAllTouched).toBeFalsy();
343-
expect(hasError).toBeFalsy();
355+
it('true will force one more update', async () => {
356+
let renderPhase = 0;
344357

345-
await changeValue(getField(wrapper, 'password'), 'Light');
346-
expect(isAllTouched).toBeTruthy();
347-
expect(hasError).toBeFalsy();
358+
const wrapper = mount(
359+
<Form initialValues={{ username: 'light' }}>
360+
<Field name="username">
361+
<Input />
362+
</Field>
363+
<Field shouldUpdate>
364+
{(_, __, form) => {
365+
renderPhase += 1;
366+
return (
367+
<span
368+
id="holder"
369+
data-touched={form.isFieldsTouched(true)}
370+
data-value={form.getFieldsValue()}
371+
/>
372+
);
373+
}}
374+
</Field>
375+
</Form>,
376+
);
348377

349-
await changeValue(getField(wrapper, 'password'), '');
350-
expect(isAllTouched).toBeTruthy();
351-
expect(hasError).toBeTruthy();
378+
const props = wrapper.find('#holder').props();
379+
expect(renderPhase).toEqual(2);
380+
expect(props['data-touched']).toBeFalsy();
381+
expect(props['data-value']).toEqual({ username: 'light' });
382+
});
352383
});
353384

354385
describe('setFields', () => {

0 commit comments

Comments
 (0)