如何将useReducer与Formik一起使用?

时间:2020-03-10 22:25:58

标签: reactjs react-hooks formik use-reducer

我有一个名为Context.js的文件,其中有一个reducer。所有这些都使用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 个答案:

答案 0 :(得分:0)

Formik处理状态中的表单,因此您可能必须像这样实现表单,以帮助您将输入数据发送到redux reducer:我希望这个示例有所帮助

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;