一旦表单的字段已经过验证,提交不会触发重新运行验证。提交表单后,有什么方法可以触发重新运行验证吗?
我有一个表单字段,如果未在特定时间范围内提交,其值可能变为无效。这不是异步的;我只是想介绍一种情况,在这种情况下,用户一段时间不会单击“提交”,而当他们最终单击时,该值将变为无效。最终形式会记住更改值后立即发生的验证结果,这意味着无论验证和提交之间经过了多长时间,不变的值仍然有效。这是我想要了解并改变的行为;在我的用例中,中间的时间很重要。我尝试使用beforeSubmit
包中的final-form-submit-listener
侦听器,但它仅提供对FormApi
对象的访问。我尝试使用pauseValidation
中的resumeValidation
和FormApi
函数,但是它们无法实现我想要的功能,或者可能是我没有正确使用它们。我感觉如何执行此操作非常痛苦,但我无法弄清楚。 ?
我创建了this Sandbox来说明我的意思。
谢谢!
更新:一些其他信息:
meta
对象。我的代码库很复杂,并且严重依赖meta
对象来显示错误消息。尝试在提交处理程序中复制该功能可能有效,但是它很笨拙,并且违反了整个代码库中使用的约定。答案 0 :(得分:2)
您已经在onSubmit
中放置了一个函数,为什么不只是添加所需的功能呢? event.preventDefault()
,然后使用您的validate函数,它是组件的一部分,您可以访问。
handleOnSubmit(e){
let value = document.querySelector("input").value
if (!!this.validate(value)){
e.preventDefault();
alert("Prevented submit event")
} else{
alert("Form submitted")
}
}
现在只需以onSubmit
prop的形式使用此函数(由于不确定组件的结构,所以我将其放置在bot中):
<Form onSubmit={this.handleOnSubmit}>...</Form>
<form onSubmit={this.handleOnSubmit}>
然后从表单组件中删除 SubmitListener装饰器:
decortaor={submitListener}
现在,它将在提交之前检查验证,如果未验证则阻止验证。
答案 1 :(得分:2)
此处的图书馆作者。人们总是会对我的假设无效的新方式而着迷。我的意思是真诚的积极态度,因为它可以促进学习。
?最终形式假设您的验证函数是“纯”或“幂等” ,即,在给定相同值的情况下,始终会返回相同结果。这就是为什么它在允许提交之前不会再次运行同步验证(只是为了再次检查)的原因:因为它已经存储了上次运行它的结果。通过使用外部计时器,您已使该假设无效。
如果您有更好/更简单/“更官方”的解决方案,我仍然很乐意看到它!
此问题无需更改器或修饰器。
更正式的方法是在this.validate
中运行检查(甚至可以重用onSubmit
)。唯一棘手的部分是错误将以meta.submitError
的形式返回,因此在显示错误时,您需要同时检查 。像这样:
答案 2 :(得分:1)
既然您要基于interval
强制执行表单的重新验证或停止提交,为什么不对提交按钮使用disabled
?
// interval less than 900 = 15 minutes
<button type="submit" disabled={this.state.interval>=900}>
Submit
</button>
我也阅读过react-final-form
的文档,但我认为除非您有使用meta
处理的特殊情况,否则它会更容易。
答案 3 :(得分:1)
还有另一个需要手动触发验证的用例:在这种情况下,我们获得了一个学生表格,如果我们有一个新学生,则必须填写一个名为 temporary password 的字段,否则字段不是必填字段,为简单起见,我们会即时更新验证模式(我们有类似的情况,每当完成某些提取操作时,都需要包含验证)。
我们应用了@ uche-ozoemena,并且效果很好,但是@ erik-r是该解决方案被认为是一种黑客手段,还是可以在需要手动触发验证的情况下用作批准的解决方法?
我们得到了类似的东西(使用fonk-final-form):
React.useEffect(() => {
if (isUserCreation) {
const newDataFormvalidationSchema = {
...dataFormvalidationSchema,
field: {
...dataFormvalidationSchema.field,
temporaryInitialPassword: [
...dataFormvalidationSchema.field.temporaryInitialPassword,
Validators.required,
],
},
};
dataFormValidation.updateValidationSchema(newDataFormvalidationSchema);
}
}, [isUserCreation]);
return (
<Form
initialValues={initialData}
mutators={{ mutateValue: mutateValue }}
onSubmit={values => {
save(values);
}}
validate={dataFormValidation.validateForm}
答案 4 :(得分:0)
所以我找到了一种方法! ?
我使用mutator并使用它的sed -i -e 's#$AUTHENTICATION_ENDPOINT#'"$AUTHENTICATION_ENDPOINT"'#g' usr/share/nginx/html/config.json
sed -i -e 's#$AUTHENTICATION_CLIENT_ID#'"$AUTHENTICATION_CLIENT_ID"'#g' /usr/share/nginx/html/config.json
nginx -g 'daemon off;'
函数来“更改”相关字段的值(我提供相同的值)。反过来,这会将表单状态的更改通知所有相关方,并触发验证。关键是在提交处理程序内部调用mutator,从而确保在提交表单时执行验证。看看this new Sandbox。
相关位如下:
changeValue
并且由于它触发了相同的验证机制,因此// this is a stateful component
...
...
mutateValue([name], state, { changeValue }) {
// change the value to the same value, thus
// triggering a revalidation of the same value
changeValue(state, name, value => value);
}
handleSubmit(values) {
alert("submitted");
}
render() {
return (
...
...
<Form
onSubmit={this.handleSubmit}
mutators={{ mutateValue: this.mutateValue }}
render={({
handleSubmit,
form: {
mutators: { mutateValue }
}
}) => {
const mutateBeforeSubmit = values => {
// supply the name of the relevant form field
mutateValue("revalidate");
// submit handler gets called if revalidation still passes
handleSubmit(values);
};
return (
<form onSubmit={mutateBeforeSubmit}>
...
...
</form>
);
}}
/>
...
...
得到相应的使用!
如果您有更好/更简单/“更官方”的解决方案,我仍然很乐意看到它!