无法仅通过 Formik 获取验证以触发 Antd 表单 - 错误字段仅在实际尝试提交时显示
Cannot get validation only to fire for Antd form with Formik - errored fields only show when actually trying to submit
我无法通过单击按钮而不是提交来仅验证(不提交)我的表单(Antd 表单)。让它验证和更新错误字段的唯一方法是我尝试提交它。有没有办法做到这一点?还是我必须提交表格?
我有一个用于提交的按钮和一个仅用于验证的按钮 - 仅验证按钮调用 validateForm 方法,但表单上没有任何更新。
编辑:这里有一个 link 到 codesandbox 来演示这个:https://codesandbox.io/s/xo5ln7l32p ...再次 -当我触摸文本框或单击提交按钮时,验证工作并在文本框下方显示错误消息,但是,当单独单击“全部验证”时,文本框下方没有显示错误。
这是我的基本 Antd 表单的代码:
import React from 'react';
import PropTypes from 'prop-types';
import { Form as AntdForm } from 'antd';
import FormValidationAlert from './FormValidationAlert';
function Form({ children, onSubmit, isValid, validationErrors }) {
return (
<AntdForm layout="vertical" onSubmit={onSubmit} style={{ margin: 20 }}>
{!isValid && <FormValidationAlert validationErrors={validationErrors} />}
{children}
</AntdForm>
);
}
Form.propTypes = {
onSubmit: PropTypes.func.isRequired,
isValid: PropTypes.bool.isRequired,
validationErrors: PropTypes.array
};
export default Form;
这是我的表格:
import React from 'react';
import PropTypes from 'prop-types';
import { Formik } from 'formik';
import * as Yup from 'yup';
import { Col, Row, Steps } from 'antd';
import {
Form,
TextInput
} from '../common/forms';
class CreateItemForm extends React.Component {
render() {
const formik = {
initialValues: {
name: ''
},
validationSchema: Yup.object().shape({
name: Yup.string().required('Name is required.')
}),
onSubmit: (values, actions) => {
this.props.onSubmit(values);
}
};
console.log('this.props', this.props);
const { setFormRef, status, currentStep } = this.props;
return (
<Formik
ref={setFormRef}
{...formik}
render={form => (
<Form
onSubmit={form.handleSubmit}
isValid={status.isValid}
validationErrors={status.validationErrors}
>
<TextInput
{...form}
name="name"
placeholder="Name"
label="Name"
/>
<button type="button" onClick={() => validateForm().then(() => console.log(blah))}>
Validate All
</button>
<button type="submit">Submit</button>
</ Form>
)}
/>
);
}
}
CreateItemForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
status: PropTypes.object.isRequired,
setFormRef: PropTypes.func.isRequired
};
export default CreateItemForm;
这是我的 TextInput:
import React from 'react';
import PropTypes from 'prop-types';
import { Form, Input } from 'antd';
import ReactInputMask from 'react-input-mask';
function TextInput({
values,
errors,
touched,
handleSubmit,
setFieldValue,
setFieldTouched,
name,
label,
placeholder,
disabled,
addOnBeforeValue,
addOnAfterValue,
mask,
maskPermanents
}) {
return (
<Form.Item
label={label}
hasFeedback={!!errors[name]}
validateStatus={touched[name] && errors[name] && 'error'}
help={touched[name] && errors[name]}
>
{mask ? (
<ReactInputMask
disabled={
disabled === null || disabled === undefined ? false : disabled
}
alwaysShowMask={false}
value={values[name]}
onChange={event => setFieldValue(name, event.target.value)}
onBlur={() => setFieldTouched(name)}
mask={mask}
permanents={maskPermanents}
>
{inputProps => (
<Input
{...inputProps}
placeholder={placeholder}
onPressEnter={handleSubmit}
addonBefore={addOnBeforeValue}
addonAfter={addOnAfterValue}
/>
)}
</ReactInputMask>
) : (
<Input
disabled={disabled}
placeholder={placeholder}
value={values[name]}
onChange={event => setFieldValue(name, event.target.value)}
onBlur={() => setFieldTouched(name)}
onPressEnter={handleSubmit}
addonBefore={addOnBeforeValue}
addonAfter={addOnAfterValue}
/>
)}
</Form.Item>
);
}
TextInput.propTypes = {
values: PropTypes.object,
errors: PropTypes.object,
touched: PropTypes.object,
handleSubmit: PropTypes.func,
setFieldValue: PropTypes.func,
setFieldTouched: PropTypes.func,
name: PropTypes.string.isRequired,
label: PropTypes.string,
disabled: PropTypes.bool,
placeholder: PropTypes.string,
addOnBeforeValue: PropTypes.string,
addOnAfterValue: PropTypes.string,
mask: PropTypes.string,
maskPermanents: PropTypes.arrayOf(PropTypes.number)
};
export default TextInput;
是的,您可以验证按钮点击而不是表单提交。
您应该考虑的几点。
- 您应该用标签包裹表单元素。
不要忘记使用导出方法 wrap with create form 方法。
export default Form.create()(SimpleForm
);
添加一个 onlick 方法并使用如下验证方法。
this.props.form.validateFieldsAndScroll((错误, 值) => {
如果(!错误){
//做你想做的事。
}
});
对字段使用正确的验证方法
祝你好运!
在验证所有按钮点击时,您可以使用 form.submitForm();
您可以在此处查看工作中的 stackblitz 演示。
代码片段
function doSave(values) {
console.log("saving data", values);
}
function validateAllClick(form) {
form.submitForm();
console.log("just validating");
}
function App() {
return (
<Layout>
<h1>Here's My Form</h1>
<Content>
<CreateItemForm
status={editModelStatus}
setFormRef={setFormRef}
onSubmit={values => doSave(values)}
onValidate={validateAllClick}
/>
</Content>
</Layout>
);
}
我想通了 - 它没有显示错误,因为 TextInput 中的 Form.Item 正在检查要首先触摸的字段:
<Form.Item
label={label}
hasFeedback={!!errors[name]}
validateStatus={touched[name] && errors[name] && 'error'}
help={touched[name] && errors[name]}
>
...将其更改为以下内容可以使它起作用(我只是删除了是否实际触摸了该字段的检查):
<Form.Item
label={label}
hasFeedback={!!errors[name]}
validateStatus={errors[name] && 'error'}
help={errors[name]}
>
我无法通过单击按钮而不是提交来仅验证(不提交)我的表单(Antd 表单)。让它验证和更新错误字段的唯一方法是我尝试提交它。有没有办法做到这一点?还是我必须提交表格?
我有一个用于提交的按钮和一个仅用于验证的按钮 - 仅验证按钮调用 validateForm 方法,但表单上没有任何更新。
编辑:这里有一个 link 到 codesandbox 来演示这个:https://codesandbox.io/s/xo5ln7l32p ...再次 -当我触摸文本框或单击提交按钮时,验证工作并在文本框下方显示错误消息,但是,当单独单击“全部验证”时,文本框下方没有显示错误。
这是我的基本 Antd 表单的代码:
import React from 'react';
import PropTypes from 'prop-types';
import { Form as AntdForm } from 'antd';
import FormValidationAlert from './FormValidationAlert';
function Form({ children, onSubmit, isValid, validationErrors }) {
return (
<AntdForm layout="vertical" onSubmit={onSubmit} style={{ margin: 20 }}>
{!isValid && <FormValidationAlert validationErrors={validationErrors} />}
{children}
</AntdForm>
);
}
Form.propTypes = {
onSubmit: PropTypes.func.isRequired,
isValid: PropTypes.bool.isRequired,
validationErrors: PropTypes.array
};
export default Form;
这是我的表格:
import React from 'react';
import PropTypes from 'prop-types';
import { Formik } from 'formik';
import * as Yup from 'yup';
import { Col, Row, Steps } from 'antd';
import {
Form,
TextInput
} from '../common/forms';
class CreateItemForm extends React.Component {
render() {
const formik = {
initialValues: {
name: ''
},
validationSchema: Yup.object().shape({
name: Yup.string().required('Name is required.')
}),
onSubmit: (values, actions) => {
this.props.onSubmit(values);
}
};
console.log('this.props', this.props);
const { setFormRef, status, currentStep } = this.props;
return (
<Formik
ref={setFormRef}
{...formik}
render={form => (
<Form
onSubmit={form.handleSubmit}
isValid={status.isValid}
validationErrors={status.validationErrors}
>
<TextInput
{...form}
name="name"
placeholder="Name"
label="Name"
/>
<button type="button" onClick={() => validateForm().then(() => console.log(blah))}>
Validate All
</button>
<button type="submit">Submit</button>
</ Form>
)}
/>
);
}
}
CreateItemForm.propTypes = {
onSubmit: PropTypes.func.isRequired,
status: PropTypes.object.isRequired,
setFormRef: PropTypes.func.isRequired
};
export default CreateItemForm;
这是我的 TextInput:
import React from 'react';
import PropTypes from 'prop-types';
import { Form, Input } from 'antd';
import ReactInputMask from 'react-input-mask';
function TextInput({
values,
errors,
touched,
handleSubmit,
setFieldValue,
setFieldTouched,
name,
label,
placeholder,
disabled,
addOnBeforeValue,
addOnAfterValue,
mask,
maskPermanents
}) {
return (
<Form.Item
label={label}
hasFeedback={!!errors[name]}
validateStatus={touched[name] && errors[name] && 'error'}
help={touched[name] && errors[name]}
>
{mask ? (
<ReactInputMask
disabled={
disabled === null || disabled === undefined ? false : disabled
}
alwaysShowMask={false}
value={values[name]}
onChange={event => setFieldValue(name, event.target.value)}
onBlur={() => setFieldTouched(name)}
mask={mask}
permanents={maskPermanents}
>
{inputProps => (
<Input
{...inputProps}
placeholder={placeholder}
onPressEnter={handleSubmit}
addonBefore={addOnBeforeValue}
addonAfter={addOnAfterValue}
/>
)}
</ReactInputMask>
) : (
<Input
disabled={disabled}
placeholder={placeholder}
value={values[name]}
onChange={event => setFieldValue(name, event.target.value)}
onBlur={() => setFieldTouched(name)}
onPressEnter={handleSubmit}
addonBefore={addOnBeforeValue}
addonAfter={addOnAfterValue}
/>
)}
</Form.Item>
);
}
TextInput.propTypes = {
values: PropTypes.object,
errors: PropTypes.object,
touched: PropTypes.object,
handleSubmit: PropTypes.func,
setFieldValue: PropTypes.func,
setFieldTouched: PropTypes.func,
name: PropTypes.string.isRequired,
label: PropTypes.string,
disabled: PropTypes.bool,
placeholder: PropTypes.string,
addOnBeforeValue: PropTypes.string,
addOnAfterValue: PropTypes.string,
mask: PropTypes.string,
maskPermanents: PropTypes.arrayOf(PropTypes.number)
};
export default TextInput;
是的,您可以验证按钮点击而不是表单提交。 您应该考虑的几点。
- 您应该用标签包裹表单元素。
不要忘记使用导出方法 wrap with create form 方法。
export default Form.create()(SimpleForm
);添加一个 onlick 方法并使用如下验证方法。
this.props.form.validateFieldsAndScroll((错误, 值) => { 如果(!错误){ //做你想做的事。 } });
对字段使用正确的验证方法
祝你好运!
在验证所有按钮点击时,您可以使用 form.submitForm();
您可以在此处查看工作中的 stackblitz 演示。
代码片段
function doSave(values) {
console.log("saving data", values);
}
function validateAllClick(form) {
form.submitForm();
console.log("just validating");
}
function App() {
return (
<Layout>
<h1>Here's My Form</h1>
<Content>
<CreateItemForm
status={editModelStatus}
setFormRef={setFormRef}
onSubmit={values => doSave(values)}
onValidate={validateAllClick}
/>
</Content>
</Layout>
);
}
我想通了 - 它没有显示错误,因为 TextInput 中的 Form.Item 正在检查要首先触摸的字段:
<Form.Item
label={label}
hasFeedback={!!errors[name]}
validateStatus={touched[name] && errors[name] && 'error'}
help={touched[name] && errors[name]}
>
...将其更改为以下内容可以使它起作用(我只是删除了是否实际触摸了该字段的检查):
<Form.Item
label={label}
hasFeedback={!!errors[name]}
validateStatus={errors[name] && 'error'}
help={errors[name]}
>