Skip to content

Commit 517bab5

Browse files
authored
feat: support onFinishFailed (#24)
* support onFinishFailed * update docs * clean up
1 parent 4b6dc9a commit 517bab5

File tree

6 files changed

+39
-14
lines changed

6 files changed

+39
-14
lines changed

README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,18 @@ We use typescript to create the Type definition. You can view directly in IDE. B
6161

6262
## Form
6363

64-
| Prop | Description | Type | Default |
65-
| ---------------- | -------------------------------------------------- | ------------------------------------- | ---------------- |
66-
| component | Customize Form render component | string \| Component \| false | form |
67-
| fields | Control Form fields status. Only use when in Redux | [FieldData](#fielddata)[] | - |
68-
| form | Set form instance created by `useForm` | [FormInstance](#useform) | `Form.useForm()` |
69-
| initialValues | Initial value of Form | Object | - |
70-
| name | Config name with [FormProvider](#formprovider) | string | - |
71-
| validateMessages | Set validate message template | [ValidateMessages](#validatemessages) | - |
72-
| onFieldsChange | Trigger when any value of Field changed | (changedFields, allFields): void | - |
73-
| onValuesChange | Trigger when any value of Field changed | (changedValues, values): void | - |
64+
| Prop | Description | Type | Default |
65+
| ---------------- | -------------------------------------------------- | ------------------------------------------ | ---------------- |
66+
| component | Customize Form render component | string \| Component \| false | form |
67+
| fields | Control Form fields status. Only use when in Redux | [FieldData](#fielddata)[] | - |
68+
| form | Set form instance created by `useForm` | [FormInstance](#useform) | `Form.useForm()` |
69+
| initialValues | Initial value of Form | Object | - |
70+
| name | Config name with [FormProvider](#formprovider) | string | - |
71+
| validateMessages | Set validate message template | [ValidateMessages](#validatemessages) | - |
72+
| onFieldsChange | Trigger when any value of Field changed | (changedFields, allFields): void | - |
73+
| onFinish | Trigger when form submit and success | (values): void | - |
74+
| onFinishFailed | Trigger when form submit and failed | ({ values, errorFields, outOfDate }): void | - |
75+
| onValuesChange | Trigger when any value of Field changed | (changedValues, values): void | - |
7476

7577
## Field
7678

examples/validate-perf.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ export default class Demo extends React.Component {
3030
console.log('Finish:', values);
3131
};
3232

33+
public onFinishFailed = errorInfo => {
34+
console.log('Failed:', errorInfo);
35+
};
36+
3337
public render() {
3438
return (
3539
<div>
@@ -38,6 +42,7 @@ export default class Demo extends React.Component {
3842
ref={this.setForm}
3943
style={{ padding: 16 }}
4044
onFinish={this.onFinish}
45+
onFinishFailed={this.onFinishFailed}
4146
validateMessages={myMessages}
4247
initialValues={{ remember: true }}
4348
>

src/Form.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export interface FormProps extends BaseFormProps {
2828
onValuesChange?: Callbacks['onValuesChange'];
2929
onFieldsChange?: Callbacks['onFieldsChange'];
3030
onFinish?: Callbacks['onFinish'];
31+
onFinishFailed?: Callbacks['onFinishFailed'];
3132
}
3233

3334
const Form: React.FunctionComponent<FormProps> = (
@@ -42,6 +43,7 @@ const Form: React.FunctionComponent<FormProps> = (
4243
onValuesChange,
4344
onFieldsChange,
4445
onFinish,
46+
onFinishFailed,
4547
...restProps
4648
}: FormProps,
4749
ref,
@@ -90,6 +92,7 @@ const Form: React.FunctionComponent<FormProps> = (
9092
onFinish(values);
9193
}
9294
},
95+
onFinishFailed,
9396
});
9497

9598
// Set initial value, init store value when first mount

src/interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ export interface Callbacks {
139139
onValuesChange?: (changedValues: Store, values: Store) => void;
140140
onFieldsChange?: (changedFields: FieldData[], allFields: FieldData[]) => void;
141141
onFinish?: (values: Store) => void;
142+
onFinishFailed?: (errorInfo: ValidateErrorEntity) => void;
142143
}
143144

144145
export interface InternalHooks {

src/useForm.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ export class FormStore {
487487
if (this.lastValidatePromise === summaryPromise) {
488488
return Promise.resolve(this.store);
489489
}
490-
return Promise.reject([]);
490+
return Promise.reject<string[]>([]);
491491
},
492492
)
493493
.catch((results: { name: InternalNamePath; errors: string[] }[]) => {
@@ -514,8 +514,12 @@ export class FormStore {
514514
onFinish(values);
515515
}
516516
})
517-
// Do nothing about submit catch
518-
.catch(e => e);
517+
.catch(e => {
518+
const { onFinishFailed } = this.callbacks;
519+
if (onFinishFailed) {
520+
onFinishFailed(e);
521+
}
522+
});
519523
};
520524
}
521525

tests/index.test.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,10 @@ describe('Form.Basic', () => {
319319

320320
it('submit', async () => {
321321
const onFinish = jest.fn();
322+
const onFinishFailed = jest.fn();
322323

323324
const wrapper = mount(
324-
<Form onFinish={onFinish}>
325+
<Form onFinish={onFinish} onFinishFailed={onFinishFailed}>
325326
<InfoField name="user" rules={[{ required: true }]}>
326327
<Input />
327328
</InfoField>
@@ -335,13 +336,22 @@ describe('Form.Basic', () => {
335336
wrapper.update();
336337
matchError(wrapper, "'user' is required");
337338
expect(onFinish).not.toHaveBeenCalled();
339+
expect(onFinishFailed).toHaveBeenCalledWith({
340+
errorFields: [{ name: ['user'], errors: ["'user' is required"] }],
341+
outOfDate: false,
342+
values: {},
343+
});
344+
345+
onFinish.mockReset();
346+
onFinishFailed.mockReset();
338347

339348
// Trigger
340349
await changeValue(getField(wrapper), 'Bamboo');
341350
wrapper.find('button').simulate('submit');
342351
await timeout();
343352
matchError(wrapper, false);
344353
expect(onFinish).toHaveBeenCalledWith({ user: 'Bamboo' });
354+
expect(onFinishFailed).not.toHaveBeenCalled();
345355
});
346356

347357
it('getInternalHooks should not usable by user', () => {

0 commit comments

Comments
 (0)