Formik重置回调创建递归问题

问题描述

我有一个非常简单的formik设置,当用户按下“重置表单”按钮时,我需要传递新的初始值。我正在关注文档,但最终创建了递归问题。

formReset()作为onReset的参数传递给formik。该函数调用,但是我不确定递归在哪里发生。

Here is a codesandbox为您方便。更改表单值,然后尝试重置表单。

App.js


// Helper styles for demo
import "./helper.css";
import { MoreResources,displayFormikState } from "./helper";

import React from "react";
import { render } from "react-dom";
import { Formik } from "formik";
import * as Yup from "yup";

const formReset = (_,{resetForm}) => {
  resetForm({email: ''});
}

const App = () => (
  <div className="app">
    <h1>
      Basic{" "}
      <a
        href="https://github.com/jaredpalmer/formik"
        target="_blank"
        rel="noopener noreferrer"
      >
        Formik
      </a>{" "}
      Demo
    </h1>

    <Formik
      initialValues={{ email: "[email protected]" }}
      
      onSubmit={async values => {
        await new Promise(resolve => setTimeout(resolve,500));
        alert(JSON.stringify(values,null,2));
      }}
      onReset={formReset}
      validationSchema={Yup.object().shape({
        email: Yup.string()
          .email()
          .required("required")
      })}
    >
      {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={handleChange}
              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>

            <displayFormikState {...props} />
          </form>
        );
      }}
    </Formik>

    <MoreResources />
  </div>
);

render(<App />,document.getElementById("root"));

解决方法

编辑:

因此...一个更好的选择是在initialValues中使用useState并传递enableReinitialize并将状态更改为“重置”表单。比尝试使用resetForm更容易。


您无需将函数传递给onReset并调用resetForm,只需将类型reset传递给按钮并使用{{1} }组件,而不是普通的html Form标签。

form组件将处理FormhandleReset一起触发的button

type="reset"

这里是working example