我已经构建了使用Formik表单的沙盒React应用程序。
如果电子邮件字段验证已触发并且有效,我想调度Redux操作。 我想调度该操作以从用户电子邮件中进行一些查找。此操作将更新redux状态并填充表单上的其他字段。
因此,如果电子邮件字段有效,则将发生此调度。其他字段可能无效,我尚未提交表格。
我该怎么做?我找不到任何文档!
https://codesandbox.io/s/x32yoo242q
谢谢!
答案 0 :(得分:1)
您可以创建可重用的自定义component
,以对input
更新进行次要操作。在这种情况下,如果输入有效且具有值,它将分派action
(redux操作),和/或如果无效则分派次要操作。
更新:使用componentDidUpdate
。它不那么冗长,并且需要较少的手动字段级别处理。另外,您还应该debounce
使用该函数来避免大量的redux操作触发器。
工作示例(电子邮件):
工作示例(材料UI选择):
组件/输入(自定义组件-componentDidUpdate
控制是否调用validateField
)
import React, { Fragment, PureComponent } from "react";
class Input extends PureComponent {
componentDidUpdate = prevProps => {
const { errors, value } = this.props;
if (errors !== prevProps.errors || value !== prevProps.value) {
this.props.validateField({ errors, value });
}
};
render = () => {
const { errors, label, name, touched, validateField, ...rest } = this.props;
return (
<Fragment>
<label htmlFor={name} style={{ display: "block" }}>
{label}
</label>
<input {...rest} name={name} />
{errors && touched && (
<div style={{ color: "red", marginTop: ".5rem" }}>{errors}</div>
)}
</Fragment>
);
};
}
export default Input;
容器/表单(validateField
控制还原操作)
import debounce from "lodash/debounce";
import React from "react";
import { withFormik } from "formik";
import Input from "../../components/Input";
import DisplayFormikState from "../../components/DisplayFormState";
import { resetMessage, setMessage } from "../../actions/message";
import store from "../../store";
import * as Yup from "yup";
const formikEnhancer = withFormik({
validationSchema: Yup.object().shape({
email: Yup.string()
.email("Invalid email address")
.required("Email is required!")
}),
mapPropsToValues: props => ({
email: ""
}),
handleSubmit: (values, { setSubmitting }) => {
const payload = {
...values
};
setTimeout(() => {
alert(JSON.stringify(payload, null, 2));
setSubmitting(false);
}, 1000);
},
displayName: "MyForm"
});
const handleFormReset = handleReset => {
store.dispatch(resetMessage());
handleReset();
};
const validateField = debounce(
({ errors, value }) =>
!errors && value
? store.dispatch(setMessage())
: store.dispatch(resetMessage()),
500
);
const MyForm = props => {
const {
values,
touched,
dirty,
errors,
handleBlur,
handleChange,
handleReset,
handleSubmit,
isSubmitting
} = props;
return (
<form onSubmit={handleSubmit}>
<Input
name="email"
label="Email"
type="email"
placeholder="Enter an email address."
errors={errors.email}
value={values.email}
touched={touched.email}
onChange={handleChange}
onBlur={handleBlur}
validateField={validateField}
/>
<button
type="button"
className="outline"
onClick={() => handleFormReset(handleReset)}
disabled={!dirty || isSubmitting}
>
Reset
</button>
<button type="submit" disabled={isSubmitting}>
Submit
</button>
<DisplayFormikState {...props} />
</form>
);
};
export default formikEnhancer(MyForm);
答案 1 :(得分:1)
使用电子邮件输入的 onBlur
处理程序,最简单,最直接的方法即可实现所需的目标。您可以通过执行以下操作来扩展默认处理程序:
<input
id="email"
placeholder="Enter your email"
type="email"
value={values.email}
onChange={handleChange}
onBlur={e => {
handleBlur(e);
if (!errors.email) {
console.log("dispatch: ", e.currentTarget.value);
}
}}
/>
首先还要调用Formik的 handleBlur
,然后保留默认的验证行为,然后再添加自己的验证行为。您的表格正在验证 onChange
和 onBlur
,因此 errors.email
应该始终准确地表示电子邮件输入的有效性,如果电子邮件在模糊时有效,我们可以使用它来调度(在我的示例中,我只是在控制台上记录了一些内容以进行说明)。检出沙盒以查看其运行情况: