2

我正在尝试学习如何使用 Formik 和 Yup 来验证输入(文本)表单字段。我遵循了 Jared Palmer 的标准方法,它开箱即用,效果很好。

当涉及到做一些更多由组件驱动的事情时,我很难达到相同的验证水平,我就是不知道哪里出了问题?

是的,似乎无法识别我的表单模型,也不会根据需要验证输入字段......

我在想我实际上已经搞砸了初始值,或者我没有以 Yup 正在寻找的正确形状提供它们,但是这里的任何帮助都会令人惊叹,这太疯狂了......

我在这里启动并运行了一个示例沙箱 >>

https://codesandbox.io/s/building-multi-step-form-with-formik-yup-vjzpk

表单模型 (components/CheckoutPage/FormModel/checkoutFormModel.js):

export default {
  formId: "checkoutForm",
  formField: {
    nestedObj: {
      firstName: {
        name: "firstName",
        label: "First name*",
        requiredErrorMsg: "First name is required"
      }
    }
  }
};

初始值 (组件/CheckoutPage/FormModel/initialValues.js):

import checkoutFormModel from "./checkoutFormModel";
const {
  formField: {
    nestedObj: { firstName }
  }
} = checkoutFormModel;

export default {
  nestedObj: {
    [firstName.name]: ""
  }
};

是的验证模式 (components/CheckoutPage/FormModel/validationSchema.js):

import * as Yup from "yup";
import checkoutFormModel from "./checkoutFormModel";
const {
  formField: {
    nestedObj: { firstName }
  }
} = checkoutFormModel;

export default [
  Yup.object().shape({
    nestedObj: Yup.object().shape({
      [firstName.name]: Yup.string().required(`${firstName.requiredErrorMsg}`)
    })
  })
];

结合了 Yup 和 Formik 的地址表单 (components/CheckoutPage/Forms/AddressForm.js):

import React from "react";
import { Grid } from "@material-ui/core";
import { InputField } from "../../FormFields";

export default function AddressForm(props) {
  const {
    formField: {
      nestedObj: { firstName }
    }
  } = props;
  return (
    <React.Fragment>
      <Grid container spacing={3}>
        <Grid item xs={12} sm={6}>
          <InputField name={firstName.name} label={firstName.label} fullWidth />
        </Grid>
      </Grid>
    </React.Fragment>
  );
}
4

1 回答 1

1

发生的情况是您的 yup 验证将验证像

{
    nestedObj: {
        [firstName.name]: '' // Validation will get here
    }
}

但是当你传递给你的输入时,你name={firstName.name}的输入会像

{
    [firstName.name]: ''
}

所以你错过了验证,因为你nestedObj在 yup 验证中添加了

或者

您忘记添加nestedObjfirstName.name.

所以你可以做的就是改变你的验证模式

Yup.object().shape({
  [firstName.name]: Yup.string().required(`${firstName.requiredErrorMsg}`)
})

或者

传递给输入,名称nestedObj

<InputField name={`nestedObj.${firstName.name}`} label={firstName.label} fullWidth />

您可以将其作为道具传递,也可以只是硬编码字符串,您可以选择。

于 2020-06-24T19:03:10.340 回答