Skip to content

Commit 4d5ec2a

Browse files
authored
Merge pull request #169 from jimengio/async-submit
fix: 表单提交异步验证失效问题
2 parents 54ff746 + c1bb0be commit 4d5ec2a

File tree

4 files changed

+71
-7
lines changed

4 files changed

+71
-7
lines changed

example/forms/async-validation.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,20 @@ let formItems: IMesonFieldItem[] = [
1515
required: true,
1616
placeholder: "不能有数字",
1717
asyncValidator: async (x, item, form) => {
18-
await new Promise((resolve, reject) => {
18+
const errInfo: string = await new Promise((resolve, reject) => {
1919
setTimeout(() => {
20-
resolve();
20+
if (x === "test") {
21+
resolve("duplicate last name");
22+
} else {
23+
resolve();
24+
}
2125
}, 1000);
2226
});
27+
28+
if (errInfo) {
29+
return errInfo;
30+
}
31+
2332
if (x?.match(/\d/)) {
2433
return "should not have digits in name";
2534
}
@@ -93,11 +102,22 @@ let formItems: IMesonFieldItem[] = [
93102
return {};
94103
},
95104
asyncValidateMultiple: async (form) => {
96-
await new Promise((resolve, reject) => {
105+
const errInfo: Record<string, string> = await new Promise((resolve, reject) => {
97106
setTimeout(() => {
98-
resolve();
107+
if (form.province === "test") {
108+
resolve({
109+
province: "province does not exist",
110+
});
111+
} else {
112+
resolve();
113+
}
99114
}, 1000);
100115
});
116+
117+
if (errInfo) {
118+
return errInfo;
119+
}
120+
101121
let ret = {
102122
province: undefined,
103123
city: undefined,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@jimengio/meson-form",
3-
"version": "0.4.22-legacy0",
3+
"version": "0.5.2-legacy2",
44
"description": "",
55
"main": "./lib/index.js",
66
"types": "./lib/index.d.ts",

src/hook/meson-core.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useState, useRef } from "react";
22
import { useImmer } from "use-immer";
33
import { IMesonFieldItem, IMesonFieldItemHasValue, FuncMesonModifyForm, IMesonCustomMultipleField, IMesonErrors, FieldValues, FieldName } from "../model/types";
44
import { validateItem, hasErrorInObject } from "../util/validation";
5-
import { traverseItems, traverseItemsReachCustomMultiple } from "../util/render";
5+
import { traverseItems, traverseItemsReachCustomMultiple, asyncCustomeValidateItems } from "../util/render";
66
import produce, { Draft } from "immer";
77
import { union, isFunction, isEmpty } from "lodash-es";
88
import { isEmptyErrorsObject } from "../util/data";
@@ -25,7 +25,7 @@ export let useMesonCore = <T extends FieldValues, TransferData>(props: {
2525
let [errors, updateErrors] = useImmer<IMesonErrors<T>>({});
2626
let modifiedState = useRef(false);
2727

28-
let onCheckSubmitWithValue = (passedForm?: T, options?: ICheckSubmitOptions<T, TransferData>) => {
28+
let onCheckSubmitWithValue = async (passedForm?: T, options?: ICheckSubmitOptions<T, TransferData>) => {
2929
let latestForm = passedForm;
3030
let currentErrors: IMesonErrors<T> = {};
3131
let hasErrors = false;
@@ -50,6 +50,30 @@ export let useMesonCore = <T extends FieldValues, TransferData>(props: {
5050
}
5151
});
5252

53+
await asyncCustomeValidateItems(props.items, latestForm, async (i) => {
54+
switch (i.type) {
55+
case "custom-multiple":
56+
const multItem = i as IMesonCustomMultipleField<T>;
57+
if (isFunction(multItem.asyncValidateMultiple)) {
58+
let results = await multItem.asyncValidateMultiple(latestForm, multItem);
59+
if (hasErrorInObject(results)) {
60+
Object.assign(currentErrors, results);
61+
hasErrors = true;
62+
}
63+
}
64+
break;
65+
default:
66+
const item = i as IMesonFieldItemHasValue<T>;
67+
if (isFunction(item.asyncValidator)) {
68+
let result = await item.asyncValidator(latestForm[item.name], item, latestForm);
69+
if (result) {
70+
currentErrors[item.name] = result;
71+
hasErrors = true;
72+
}
73+
}
74+
}
75+
});
76+
5377
updateErrors((draft) => {
5478
return currentErrors;
5579
});

src/util/render.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,23 @@ export function traverseItemsReachCustomMultiple<T extends FieldValues>(xs: IMes
3636
}
3737
});
3838
}
39+
40+
export async function asyncCustomeValidateItems<T extends FieldValues>(xs: IMesonFieldItem<T>[], form: T, method: (x: IMesonFieldItem<T>) => void) {
41+
const xsPromises = xs.map(async (x) => {
42+
if (x.shouldHide != null && x.shouldHide(form)) {
43+
return null;
44+
}
45+
46+
switch (x.type) {
47+
case "decorative":
48+
return;
49+
case "nested":
50+
case "group":
51+
await asyncCustomeValidateItems(x.children, form, method);
52+
default:
53+
await method(x);
54+
}
55+
});
56+
57+
await Promise.all(xsPromises);
58+
}

0 commit comments

Comments
 (0)