在 Formik 字段选择和 Yup 验证中继续显示错误消息

问题描述 投票:0回答:1

我第一次尝试使用 formik 和 yup valiation, 我创建了一个选择字段并放置了一些选项, 每次选择该选项后,它都会显示验证错误消息,

谁能帮我解决这个问题

错误的codesandbox链接

https://codesandbox.io/s/sweet-dubinsky-w6cmws

    const InvestmentDetail = ({ data, changeValue }) => {
      return (
        <div className="text-2xl flex flex-col w-full justify-between container w-[1128px] gap-[42px] pt-[35px] pb-[50px] ">
          {investmentDetails.map((i, _i) => {
            return (
              <>
                <div>
                  <div className="text-[22px]"> {i.label} </div>
                  <div className="text-lg text-[#404040]"> {i.desc}</div>
                </div>
                <div className="flex flex-col w-full">
                  <Field
                    as="select"
                    name={i.label}
                    id="dropdown"
                    className="appearance-none relative !w-full p-[16px] h-[4.06rem] border-[#787878] rounded-[6px] border-solid border-[1px] bg-[#fff]"
                    value={data[i.label]}
                    onChange={(e) => changeValue(i.label, e.target.value)}
                  >
                    <option value="" className="text-2xl">
                      Select
                    </option>
    
                    {i.options.map((i) => (
                      <>
                        <option key={i} value={i} className="text-2xl">
                          {i}
                        </option>
                        <br />
                      </>
                    ))}
                  </Field>
                  <ErrorMessage
                    name={i.label}
                    component="div"
                    className="error  bottom-[-10px] text-[red] text-xl"
                  />
                </div>
              </>
            );
          })}
        </div>
      );
    };
    
    export default function App() {
      const [formData, setFormData] = useState(initialStates);
      useEffect(() => {}, [formData, setFormData]);
      const changeValue = (key, value) => {
        setFormData((prevData) => ({
          ...prevData,
          [key]: value
        }));
      };
    
      return (
        <>
          <Formik
            initialValues={initialValues}
            validationSchema={validationSchema}
            onSubmit={() => console.log("high")}
          >
            <Form>
              <InvestmentDetail data={formData} changeValue={changeValue} />
            </Form>
          </Formik>{" "}
        </>
      );

}

验证模式和初始状态:

import * as Yup from "yup";
export const investmentDetails = [
  {
    label: "Account Type",
    desc: "",
    options: ["Saving", "Current"]
  },
  {
    label: "Portfolio/Strategy Name",
    desc: "",
    options: ["Saving", "Current"]
  },
  {
    label: "Fund Fees Category",
    desc: "Fees preview according to selection",
    options: ["Saving", "Current"]
  },
  {
    label: "Investment Category",
    desc: "Preview only when systematic transfer plan is selected",
    options: ["Saving", "Current"]
  },
  {
    label: "Country of Tax Residency",
    desc: "Preview only when systematic transfer plan is selected",
    options: ["Saving", "Current"]
  },
  {
    label: "No. of Account Holders",
    desc: "Preview only when systematic transfer plan is selected",
    options: ["Saving", "Current"]
  },

  {
    label: "Investment Mode",
    desc: "Preview only when systematic transfer plan is selected",
    options: ["Saving", "Current"]
  }
];

export const initialValues = {
  "Account Type": "",
  "Portfolio/Strategy Name": "",
  "Fund Fees Category": "",
  "Investment Category": "",
  "Communication Address": "",
  "Country of Tax Residency": "",
  "No. of Account Holders": "",
  "Quantum of Investment": "",
  "Investment Mode": ""
};

export const initialStates = {
  "Account Type": "",
  "Portfolio/Strategy Name": "",
  "Fund Fees Category": "",
  "Investment Category": "",
  "Communication Address": "",
  "Country of Tax Residency": "",
  "No. of Account Holders": 1,
  "Quantum of Investment": "",
  "Investment Mode": ""
};
export const validationSchema = Yup.object().shape({
  "Account Type": Yup.string().required("Required"),
  "Portfolio/Strategy Name": Yup.string().required("Required"),
  "Fund Fees Category": Yup.string().required("Required"),
  "Investment Category": Yup.string().required("Required"),
  "Country of Tax Residency": Yup.string().required("Required"),
  "No. of Account Holders": Yup.number()
    .required("Required")
    .min(1, "Should be at least 1"),

  "Investment Mode": Yup.string().required("Required")
});
reactjs formik yup
1个回答
0
投票

您应该使用

formik
功能来访问或更改应用程序中的值,并防止在
onChange
组件的
Field
属性上设置字段值,因为
<Field/>
自动设置文档中提到的值。

<Field />
将自动将输入连接到 Formik。它使用 name 属性来匹配 Formik 状态。将默认为 HTML 元素。

    <Field
      as="select"
      name={i.label}
      id="dropdown"
      className="appearance-none relative !w-full p-[16px] h-[4.06rem] border-[#787878] rounded-[6px] border-solid border-[1px] bg-[#fff]"
      value={data[i.label]}
    >
      <option value="" className="text-2xl">
        Select
      </option>

      {i.options.map((i) => (
        <>
          <option key={i} value={i} className="text-2xl">
            {i}
          </option>
          <br />
        </>
      ))}
    </Field>

实际上

formData
App 组件中的 setState 是多余的,您将在 onSubmit 回调上访问值,如下所示:

<Formik
  validateOnChange={true}
  initialValues={initialValues}
  validationSchema={validationSchema}
  onSubmit={(values, actions) => {
    setTimeout(() => {
      alert(JSON.stringify(values, null, 2));
      actions.setSubmitting(false);
    }, 1000);
  }}
>
  <Form>
    <InvestmentDetail data={formData} changeValue={changeValue} />
  </Form>
</Formik>
© www.soinside.com 2019 - 2024. All rights reserved.