reactjs 为什么yup“when”值总是未定义

vshtjzan  于 2023-03-12  发布在  React
关注(0)|答案(1)|浏览(253)

我的项目有Yup 0.32.11withFormik 2.2.9,我尝试使用**Yup.mixed().when(...)**方法来控制基于兄弟字段的验证消息。传入when(...)方法的兄弟字段的值总是未定义的,我不知道为什么。
具体来说,我希望在“国家”字段为“美国”/空时,“州”字段验证要求错误消息显示“州是必需的”,而在“国家”字段为其他字段时,显示“省是必需的”。
说明这个问题的示例代码andbox(包括下面的所有代码片段)是here
表格的部分定义:

<Formik
      initialValues={{
        name: "",
        mailingAddress: {
          line: "",
          city: "",
          state: "",
          country: ""
        }
      }}
      validationSchema={ValidationSchema}
      ...
>

下面是我尝试过的验证模式的4种不同变体,它们的行为都好像兄弟字段(Country)是未定义的:

const ValidationSchema = Yup.object({
  name: Yup.string().required(),
  mailingAddress: Yup.object({
    line: Yup.string().required(),
    city: Yup.string().required(),
    country: Yup.string().required(),
    //=== attempt 1 ... always returns province ===
    state: Yup.mixed().when("mailingAddress.country", {
      is: "US",
      then: Yup.string().trim().required(stateMsg),
      otherwise: Yup.string().trim().required(provinceMsg)
    })
    //=== attempt 2 ... always returns state ===
    // state: Yup.mixed().when("mailingAddress.country", {
    //   is: (value: string) => (value === undefined || value === "" || value === "US"),
    //   then: Yup.string().trim().required(stateMsg),
    //   otherwise: Yup.string().trim().required(provinceMsg)
    // })
    //=== attempt 3 ... always returns state ===
    // state: Yup.mixed().when("mailingAddress.country", {
    //   is: (value: string) => {
    //       return (value === undefined || value === "" || value === "US");
    //   },
    //   then: Yup.string().trim().required(stateMsg),
    //   otherwise: Yup.string().trim().required(provinceMsg)
    // })
    //=== attempt 4 ... always returns state ===
    // state: Yup.mixed().when("mailingAddress.country", (value, context) => {
    //   if (value === undefined || value === "" || value === "US") {
    //     return Yup.string().trim().required(stateMsg);
    //   } else {
    //     return Yup.string().trim().required(provinceMsg);
    //   }
    // })
    //=== the end ===
  })
});
axr492tv

axr492tv1#

这里有一个变通方案,使用test代替when,但不幸的是,它需要多次传递数据,因此仍然希望有一个更好的答案。

state: Yup.string().trim()
    .test("mailingAddressState-US", stateMsg, (value, context) => {
        let state = value || "";
        let country = context.parent.country || "";
        return (country !== "US" || state > "");
    })
    .test("mailingAddressState-nonUS", provinceMsg, (value, context) => {
        let state = value || "";
        let country = context.parent.country || "";
        return (country === "US" || state > "");
    }),

相关问题