🐛[BUG] ProTable 使用 ignoreRules + onValuesChange 调用 formeRef.submit() 无法触发request
提问前先看看:
https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md
🐛 bug 描述
在 ProTable 的 form 配置中使用 ignoreRules: false 且在 onValuesChange 中调用 formRef.current?.submit() ,具备rules的表单触发valuechange 和submit,但是无法按预期触发request。
使用 setTimeout 或 requestAnimationFrame 等变通方法来确保表单状态更新后再调用formRef.current?.submit() 提交可以解决。
可能是在触发 onValuesChange 时,表单状态还没有完全更新
📷 复现步骤
- 创建一个 ProTable 组件,配置具备rules的search formItem columns配置
- ProTable配置
form属性,1. 设置 ignoreRules 为false使 rules生效, 2. 设置onValuesChange回调 - 在
onValuesChange回调中直接调用formRef.current?.submit() - 控制台观察到search表单可以触发valuechange,再触发 submit,但是id表单(具备rules)不会触发后续流程(proTable的request),也不会触发校验,而titile表单(不具备rules)可以正常触发request
可复现代码:
<ProTable
columns={columns}
formRef={formRef}
request={async (params) => {
console.log('触发request', params);
return {
data: [{ id: 1, title: '123' }],
success: true,
total: 1,
};
}}
form={{
ignoreRules: false,
onValuesChange: (changedValues: any, allValues: any) => {
console.log("onValuesChange", changedValues, allValues);
// ✅ 输入title表单项(没有rules),可以正常在change后触发request
// ❌ 但是当修改id表单项(具备rules的表单item)时没有触发后续流程(request),可以正常触发valuechange且取到formref以及调用submit
formRef.current?.submit();
// 使用settimeout 0 或者使用 Promise.resolve().then() 包裹formref可以解决
},
}}
/>
const columns: ProColumns<GithubIssueItem>[] = [
{
title: 'id',
dataIndex: 'id',
},
{
title: 'Title',
dataIndex: 'title',
formItemProps: {
rules: [
{
required: true,
message: 'This field is required',
},
],
},
},
];
🏞 期望结果
在 onValuesChange 回调中直接调用 formRef.current?.submit() 应该能够正常工作,无需使用 setTimeout 或其他变通方法。
💻 复现代码
https://codesandbox.io/p/sandbox/misty-cache-yjdr6m
© 版本信息
- ProComponents 版本: 2.8.6
- umi 版本
- 浏览器环境
- 开发环境:mac OS
🚑 其他信息
猜测在 src/form/BaseForm/BaseForm.tsx 最接近 Ant Design Form 的地方统一修复:
- 在 ProTable 的 form 配置中定义 onValuesChange 回调被传递给 FormRender 组件
- FormRender组件将它传递给 BetaSchemaForm 组件
- BetaSchemaForm 组件将它传递给 ProForm 组件
- ProForm 组件基于 BaseForm 组件
- BaseForm 组件最终将它传递给 Ant Design 的 Form 组件
Hi @luojinan! I'm Dosu and I’m helping the pro-components team.
这个问题的根本原因是 React 和 Ant Design Form 的状态更新是异步的:在 onValuesChange 回调里同步调用 formRef.current?.submit() 时,表单的内部状态还没完全更新,所以校验和 request 没有被正确触发,尤其是带有 rules 的字段。社区常用的解决方法是用 setTimeout 或 Promise.resolve().then() 等方式延迟 submit,这样可以保证表单状态已经更新完毕,提交时能正确触发校验和 request(相关源码分析)。
目前没有官方文档或最佳实践专门解决这个问题,延迟 submit 是社区公认的 workaround。近期的 PR 和 issue 也没有针对这个行为的修复(相关 PR 还未合并)。建议在 onValuesChange 里用 setTimeout 或 Promise.resolve().then() 包裹 submit,确保表单状态和校验同步。
如果后续有官方修复或更优方案,建议关注 pro-components 仓库的更新。
To reply, just mention @dosu.
How did I do? Good | Irrelevant | Incorrect | Verbose | Hallucination | Report 🐛 | Other