Как использовать useReducer вместе с Formik?

У меня есть файл Context.js, в котором есть редуктор. Все это передается другим компонентам с помощью Context API.

const reducer = (state, action) => {
   switch (action.type) {
      case "SET_NAME":
         return {...state, name: action.payload}
      case "SET_LASTNAME":
         return {...state, lastname: action.payload}
      case "SET_EMAIL":
         return {...state, email: action.payload}
      default:
         return state
}

Во многих других компонентах я пытаюсь использовать Formik для работы с формами и хотел бы сохранить информацию формы в состоянии, чтобы при доступе к форме через другие компоненты там можно было найти уже предоставленную информацию.

<label htmlFor="name">Nome</label>
    <Field maxLength="51"
           name="name" 
           value={name} 
           type="text" 
           onChange={(e) => dispatch({ type: "SET_NAME", payload: e.target.value })}
    />
    <ErrorMessage name="name" />

Если я пытаюсь зарегистрировать "имя", оно работает нормально, но когда я выхожу из поля, появляется сообщение об ошибке, как если бы ничего не было набрано.

Я не могу понять, как использовать Formik вместе с useReducer или как передавать его информацию другим компонентам.

1 ответ

Formik обрабатывает формы в состоянии, поэтому вам, возможно, придется реализовать вашу форму таким образом, чтобы помочь вам отправить ваши входные данные в редуктор redux: я надеюсь, что этот пример поможет

import React from "react";
import { Formik } from "formik";
import { useDispatch } from 'react-redux';

const MyForm = () => {
  const dispatch = useDispatch();

  return (
    <Formik
      initialValues={{ email: "" }}
      onSubmit={async values => {
        await new Promise(resolve => setTimeout(resolve, 500));
        alert(JSON.stringify(values, null, 2));
      }}
    >
      {props => {
        const {
          values,
          touched,
          errors,
          dirty,
          isSubmitting,
          handleChange,
          handleBlur,
          handleSubmit,
          handleReset
        } = props;
        return (
          <form onSubmit={handleSubmit}>
            <label htmlFor="email" style={{ display: "block" }}>
              Email
            </label>
            <input
              id="email"
              placeholder="Enter your email"
              type="text"
              value={values.email}
              onChange={(e) => {
                 console.log(e.target.value);
                 // send input data to formik
                 handleChange(e);

                 // dispatch to reducer
                 dispatch({ type: "SET_NAME", payload: e.target.value });
              }}
              onBlur={handleBlur}
              className={
                errors.email && touched.email
                  ? "text-input error"
                  : "text-input"
              }
            />
            {errors.email && touched.email && (
              <div className="input-feedback">{errors.email}</div>
            )}

            <button
              type="button"
              className="outline"
              onClick={handleReset}
              disabled={!dirty || isSubmitting}
            >
              Reset
            </button>
            <button type="submit" disabled={isSubmitting}>
              Submit
            </button>

            <pre
               style={{
                  background: '#f6f8fa',
                  fontSize: '.65rem',
                  padding: '.5rem',
               }}
            >
               <strong>props</strong> ={' '}
               {JSON.stringify(formik.values, null, 2)}
            </pre>
          </form>
        );
      }}
    </Formik>
  )
};

export default MyForm;
Другие вопросы по тегам