問題描述
我的頁面用antd的Form寫的,如下:

頁面的部分樣子
在渲染的時候大部分Form.Item不會被渲染出來。這在使用的時候倒是沒什么問題,但是到了提交的時候,因為Form.Item沒有渲染,哪怕未選中的那些項有錯誤的值,也因為沒有觸發(fā)校驗而順利提交了。
當然,下下策是最后提交的時候手動遍歷數(shù)組然后自己寫校驗代碼也可以,但是這極不靈活而且一定程度上失去了使用Form的意義——我用它不就是干這個的嗎,那校驗我又自己重寫了,用它干嘛。
問了一下身邊的人,答曰,你讓他全部渲染出來不就好了。
……
在不短的沉默后,我們都笑了。
嘗試
我知道多節(jié)點渲染的優(yōu)化解決方案里就有虛擬滾動,就是只渲染需要展示的節(jié)點。
但是我很好奇這個頁面全部渲染的情況下能有多卡。
數(shù)據(jù)如下:

節(jié)點全部渲染后,點擊新增按鈕的性能數(shù)據(jù)
就算不看數(shù)據(jù),就是隨便做一個操作感覺上就像一個世紀那么漫長。
所以我還是改回來了。

目前的方案,點擊新增按鈕的性能數(shù)據(jù)
解決
我想到一個好辦法。
提交的時候覆蓋上一個蒙層,弄一個loading告訴用戶在校驗中。
然后依次去選中,然后每次選完了就去調(diào)用form.validateFields()。
如果出錯了,剛好停下來,讓用戶去改錯誤。
代碼
const onFinishFailed = ({ errorFields }) => {
if (errorFields?.length) {
errorFields.forEach(
(cur) => cur?.errors[0] && message.error(cur?.errors[0]),
);
}
};
const clickEveryPlayCheckError = async (values, curIndex = 0) => { // 依次點擊,依次校驗,發(fā)現(xiàn)有錯誤就停下來報錯
if (values?.playSteps?.length <= curIndex) return true;
console.log('submit validating...', curIndex);
editPlayRef?.current?.updateActiveItem(values?.playSteps[curIndex]); // 更換當前展示的item
await new Promise((resolve) => setTimeout(resolve, 10));
try {
await form.validateFields();
return clickEveryPlayCheckError(values, 1 + curIndex);
} catch (error) {
console.log('err', error);
onFinishFailed(error);
}
return false;
};
const onFinish = async (values) => {
console.log("submit", values); // eslint-disable-line
setSubmitValidating(true);
const validateRes = await clickEveryPlayCheckError(values);
setSubmitValidating(false);
if (!validateRes) return;
// ……
}
效果如下

提交校驗效果