Formik отправляет действие Redux после корректного изменения поля - PullRequest
1 голос
/ 14 апреля 2019

Я создал это приложение React для песочницы, которое использует формы Formik.

Я хочу отправить действие Redux, если проверка поля электронной почты запускается и является действительной.Я хочу отправить действие, чтобы сделать поиск из электронной почты пользователей.Это действие обновит состояние избыточности и заполнит некоторые другие поля в моей форме.

Таким образом, эта отправка произойдет, если поле электронной почты будет действительным.Другие поля могут быть недействительными, и я еще не отправил форму.

Как мне это сделать?Я не могу найти никакой документации по этому вопросу!

https://codesandbox.io/s/x32yoo242q

Спасибо!

Ответы [ 2 ]

1 голос
/ 14 апреля 2019

Самый простой и простой способ достичь желаемого - использовать обработчик 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);
    }
  }}
/>

Кроме того, сначала вызывая handleBlur Formik, вы сохраняете поведение проверки по умолчанию, а затем добавляете свое собственное. Ваша форма проверяет onChange, а также onBlur, поэтому errors.email всегда должны давать точное представление о действительности для ввода электронной почты, который мы можно использовать для отправки, если электронная почта действительна при размытии (в моем примере я просто что-то записываю на консоль для иллюстрации). Проверьте песочницу , чтобы увидеть ее в действии:

Edit Formik 1.2 x React Select Example

1 голос
/ 14 апреля 2019

Вы можете создать пользовательский component для повторного использования, который вызывает дополнительное действие при input обновлениях. В этом случае он отправит action (действие приставки), если вход является действительным и имеет значение, и / или при необходимости отправит вторичное действие, если оно недействительно.

Обновление : Использовать componentDidUpdate. Это менее многословно и требует меньше ручной обработки на уровне поля. Кроме того, вы также должны debounce использовать функцию, чтобы избежать большого количества триггеров избыточных действий.

Рабочий пример (электронная почта) :

Edit Formik Redux Yup Example

Рабочий пример (Выбор пользовательского интерфейса материала) :

Edit Formik Redux Yup MaterialUI


компоненты / ввод (пользовательский компонент - 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);
...