【问题标题】:React, Yup, Formik. How to extend current schema from another schema反应,是的,Formik。如何从另一个模式扩展当前模式
【发布时间】:2021-09-08 17:00:51
【问题描述】:

有很多方案,它们由一些相同的字段组合而成。更改一个方案的字段时,您需要更改相同的字段,但在其他方案中。我希望不同方案的字段,或方案本身,引用或继承一个通用方案。比如:


    import * as Yup from "yup";
    import {commonSchema} from "./common";

    export const parentSchema = Yup.object().shape({
      FirstName: Yup.string()
        .min(2, `Имя не может состоять менее чем из 2 сомволов`)
        .max(50, `Имя не может состоять более чем из 50 сомволов`)
        .required(`Поле 'Имя' обязательное для заполнения`),
      SecondName: ref(commonSchema.SecondName)
    });


    // commonSchema

    export const commonSchema = Yup.object().shape({
      SecondName: Yup.string()
        .min(2, `Отчество не может состоять менее чем из 2 сомволов`)
        .max(100, `Отчество не может состоять более чем из 100 сомволов`)
    });

简而言之,对一个通用架构进行更改将不必更改具有相同字段的其他架构。

我想在一个文件中收集所有常用属性。然后从每个文件中引用必要的属性

【问题讨论】:

    标签: reactjs formik yup


    【解决方案1】:

    Yup 中最接近模式扩展/继承的方法是使用 object.shape 基于现有架构创建新架构: Yup documentation

    object.shape(fields: object, noSortEdges?: Array<[string, string]>): Schema

    定义对象的键和所述键的模式。 请注意,您可以链接 shape 方法,其作用类似于对象扩展

    const baseSchema = Yup.object().shape({
       id: string().isRequired(),  
      name: string().isRequired()
    })
    
    const someSchema = baseSchema.shape({
       id: number().isRequired(),
       age: number().isRequired()
    })
    

    相当于:

    const someSchema = Yup.object().shape({
       id: number().isRequired(), // notice how 'id' is overridden by child schema
       name: string().isRequired(),
       age: number().isRequired()
    })
    

    另一种方法是使用concat(schema)通过组合两个schema来创建一个新的schema实例:Yup documentation

    mixed.concat(schema: Schema): Schema 通过组合两个架构来创建架构的新实例。只能连接相同类型的模式。

    const baseSchema = Yup.object().shape({
       name: string().isRequired()
    })
    
    const someSchema = baseSchema.concat(
       Yup.object().shape({
        age: number().isRequired()
    }))
    
    // someSchema will be equipped with both `name` and `age` attributes 
    

    请注意,concat 仅在两个架构对象具有不同属性或具有完全相同类型的相同属性时才有效。

    【讨论】:

    • 因为包大小从 yup 导入你需要的东西,比如 import { object, string, array } from 'yup'。可以使用 object({ name: blah }) 而不是 object().shape({ name: blah })。 shape 在我的情况下不起作用,但 concat 完成了这项工作
    【解决方案2】:

    你可以这样做:

    const CommonSchema = {
      firstName: Yup.string().required('First name is required')
    };
    
    const SchemaWithJustFirstName = Yup.object().shape({
      ...CommonSchema,
    });
    
    const SchemaWithSecondName = Yup.object().shape({
      ...CommonSchema,
      secondName: Yup.string().required('Second name is also required')
    });
    

    【讨论】:

    • 谢谢,但这是没有 Yup func 的方法。有没有扩展功能?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-20
    • 2022-07-05
    • 1970-01-01
    • 2019-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多