动态创建Yup嵌套对象架构

时间:2019-09-13 17:50:01

标签: javascript formik yup

对于此“平面”对象验证

const fields = [
  {label: 'Name', name: 'name', validation: yup.string().required()},
  {label: 'City', name: 'city', validation: yup.string().required()},
  {label: 'Phone', name: 'phone'},
]

我创建了createYupSchema函数以从fields获取Yup模式对象。

const createYupSchema = (fields ) => {
  const schema = fields.reduce((schema, field) => {
      return field.validation 
      ? {...schema, [field.name]: field.validation} 
      : schema
  }, {})

  return yup.object().shape(schema)
}

输出是Yup对象:

yup.object().shape({
  name: yup.string().required(),
  city: yup.string().required(),
}) 

但是我将有可能在fields

中使用嵌套对象
const fields = [
  {label: 'Name', name: 'name', validation: yup.string().required()},
  {label: 'Address', name: 'address.city', validation: yup.string().required()},
  {label: 'Phone', name: 'phone'},
]

所以Yup对象应该是:

yup.object().shape({
  name: yup.string().required(),
  address: yup.object().shape({
      city: yup.string().required()
  }),
}) 

是否可以从fields创建这种类型的Yup对象?

1 个答案:

答案 0 :(得分:0)

我解决了我的问题。现在createYupSchema以这种方式工作

const createYupSchema = fields => {
  const schema = fields.reduce((schema, field) => {
    const isObject = field.name.indexOf(".") >= 0;

    if (!field.validation) {
      return schema;
    }

    if (!isObject) {
      return { ...schema, [field.name]: field.validation };
    }

    const reversePath = field.name.split(".").reverse();
    const currNestedObject = reversePath .slice(1).reduce((yupObj, path) => {
        return { [path]: yup.object().shape(yupObj) };
    }, {[reversePath [0]]: field.validation});

    return { ...schema, ...currNestedObject };
  }, {});

  return yup.object().shape(schema);
};