简体   繁体   English

如何使用 React/Formik 和 Yup 验证将此对象嵌套在另一个对象中?

[英]How can I nest this Obejct inside another using React/Formik and Yup validation?

I'm trying to learn how to use Formik and Yup to validate an input(text) form field.我正在尝试学习如何使用 Formik 和 Yup 来验证输入(文本)表单字段。 I've follwed the standard approach by Jared Palmer and it worked great straight out of the box.我遵循了 Jared Palmer 的标准方法,它开箱即用,效果很好。

When it comes to doing something a little more component driven, I'm having a tough time achieveing the same level of valdation and I just can't work out where I'm going wrong?当涉及到做一些更多由组件驱动的事情时,我很难达到相同的验证水平,我就是不知道哪里出了问题?

Yup doesn't seem to be able to identify my Form Model and won't validate the input field as required...是的,似乎无法识别我的表格 Model 并且不会按要求验证输入字段...

I'm thinking that I've actually messed up the Initial Values or I'm not providing them in the right shape that Yup is looking for, but any assitance here would be amazing, this is driving mad...我在想我实际上已经搞砸了初始值,或者我没有以 Yup 正在寻找的正确形状提供它们,但是这里的任何帮助都会令人惊叹,这太疯狂了......

I have an example sandbox up and running here > >我在这里启动并运行了一个示例沙箱 >>

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

Form Model (components/CheckoutPage/FormModel/checkoutFormModel.js):表格 Model (组件/CheckoutPage/FormModel/checkoutFormModel.js):

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

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

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

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

Yup Validation Schema (components/CheckoutPage/FormModel/validationSchema.js):是的验证模式(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}`)
    })
  })
];

Address Form which combines Yup and Formik (components/CheckoutPage/Forms/AddressForm.js):结合了 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>
  );
}

What happens where is that your yup validation will validate an object like发生的情况是您的 yup 验证将验证 object 之类的

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

But when you pass to your input name={firstName.name} your input is going to be like但是当你传递给你的输入name={firstName.name}你的输入会像

{
    [firstName.name]: ''
}

So you are missing the validation because you added nestedObj in the yup validation所以你错过了验证,因为你在 yup 验证中添加了nestedObj

OR或者

You forgot to add nestedObj to the firstName.name .您忘记将nestedObj添加到firstName.name

So what you can do is change your validation schema to所以你可以做的就是改变你的验证模式

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

OR或者

Pass to the input, the name nestedObj传递给输入,名字nestedObj

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

You can pass it as a prop or just hardcode string, you choose.您可以将其作为道具传递,也可以只是硬编码字符串,您可以选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM