Вы можете создать пользовательский component
для повторного использования, который вызывает дополнительное действие при input
обновлениях. В этом случае он отправит action
(действие приставки), если вход является действительным и имеет значение, и / или при необходимости отправит вторичное действие, если оно недействительно.
Обновление : Использовать componentDidUpdate
. Это менее многословно и требует меньше ручной обработки на уровне поля. Кроме того, вы также должны debounce
использовать функцию, чтобы избежать большого количества триггеров избыточных действий.
Рабочий пример (электронная почта) :
Рабочий пример (Выбор пользовательского интерфейса материала) :
компоненты / ввод (пользовательский компонент - 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);