reactjs - Cómo validar correctamente y enviar si el formulario es válido con el formulario de ant design con typescript
Construyo un formulario sencillo con React, Redux, TypeScript y Ant Design. Siguiendo la documentación de Ant Design, creé un pequeño formulario usando los métodos getFieldDecorator y Form.create proporcionados. Todo funciona bien hasta ahora y la validación es manejada por Ant Design al ingresar datos en los campos. Mi principal problema es con el envío del formulario. Quiero enviar los datos solo si el formulario está validado y, por lo tanto, el formulario es "válido".
La documentación oficial usa validateFields para validar el formulario y devuelve una variable que contiene los errores y detiene la ejecución posterior para que el formulario no se envíe. Ahora, con TypeScript tengo las siguientes firmas: validateFields(): void; <- Uso este método para activar la validación al enviar el formulario y, después, llamo a getFieldsError(names?: Array<string>): Record<string, string[] | undefined>;
Ahora, si miras el código de ejemplo, la parte fea es usar una variable "allValid" para verificar si el formulario es válido o no. Pensé que debe haber una manera más sencilla de validar y enviar datos si el formulario es válido.
const UploadForm: FunctionComponent<FormComponentProps> = props => {
const { getFieldDecorator, validateFields, getFieldsError } = props.form;
const dispatch = useDispatch();
return (
<Form
{...formItemLayout}
onSubmit={event => {
event.preventDefault();
validateFields();
const validationErrors = getFieldsError();
let allValid = true;
console.log(validationErrors);
for (let key in validationErrors) {
console.log(validationErrors[key]);
if (validationErrors[key] !== undefined) {
allValid = false;
break;
}
}
if (allValid) {
dispatch(submitFormData());
}
}}
>
<ImageComponent />
<Form.Item label="E-mail">
{getFieldDecorator("email", {
rules: [
{
type: "email",
message: "The input is not valid E-mail!"
},
{
required: true,
message: "Please enter your E-mail!"
}
]
})(
<Input
prefix={<Icon type="mail" style={{ color: "rgba(0,0,0,.25)" }} />}
placeholder="Your e-mail"
/>
)}
</Form.Item>
<Form.Item {...buttonItemLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};
export default Form.create < FormComponentProps > {}(UploadForm);
Respuesta #1
Puedes usar Object.values() y Array.find() para encontrar el valor undefined.
validateFields();
const validationErrors = Object.values(getFieldsError());
if (!validationErrors.find(e => e === undefined)) dispatch(submitFormData());
O puedes desactivar el Botón de enviar.
Valida cada Form.Item y permite enviar solo cuando todo el estado de validación sea success.
<Button
type="primary"
htmlType="submit"
disabled={!(validateEmptyField(name) && validateEmptyField(surName))}
>
Submit
</Button>;
Usa validateStatus para validar cada Form.Item:
function FromValidate() {
const [name, setName] = useState('');
const [surName, setSurName] = useState('');
return (
<Flexbox>
<Form
onSubmit={e => {
e.preventDefault();
console.log('name', name);
console.log('surName', surName);
}}
>
<Form.Item
label="Name"
required={true}
validateStatus={validateEmptyField(name) ? 'success' : 'error'}
help={!validateEmptyField(name) && 'Name cannot be empty'}
>
<Input
placeholder="Unique Identifier"
value={name}
onChange={e => setName(e.target.value)}
/>
</Form.Item>
...
<Form.Item>
<Button
type="primary"
htmlType="submit"
disabled={
!(validateEmptyField(name) && validateEmptyField(surName))
}
>
Submit
</Button>
</Form.Item>
</Form>
</Flexbox>
);
}
Respuesta #2
Solo haz esto
try {
await form.validateFields()
console.log(form.getFieldValue())
} catch (e) {
console.log("Not a valid form")
}