Реагируй, Да, Формик. Как расширить текущую схему из другой схемы

#reactjs #formik #yup

Вопрос:

Существует много схем, и они объединены некоторыми одинаковыми полями. При изменении полей одной схемы вам нужно изменить те же поля, но в других схемах. И я хотел, чтобы поля разных схем или сами схемы ссылались на одну общую схему или наследовали ее. Что-то вроде:

 
    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 сомволов`)
    });
 

Короче говоря, для внесения изменений в одну общую схему не потребуется вносить изменения в другие схемы с теми же полями.

Я хотел бы собрать все общие свойства в одном файле. А затем обратитесь к необходимым свойствам из каждого файла

Ответ №1:

Самое близкое к расширению/наследованию схемы в Yup-использовать object.shape для создания новой схемы на основе существующей схемы: документация Yup

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

Определите ключи объекта и схемы для указанных ключей. Обратите внимание, что вы можете использовать метод формы цепочки, который действует как расширение объекта

 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) для создания нового экземпляра схемы путем расчесывания двух схем: Да, документация

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 это работает только тогда, когда два объекта схемы имеют разные свойства или одинаковые свойства с одинаковым типом.

Комментарии:

1. из-за размера пакета импортируйте из yup то, что вам нужно, например, импортируйте { объект, строку, массив } из «yup». объект({ имя: бла }) вместо объекта().можно использовать форму({ имя: бла }). форма не сработала в моем случае, но конкат справился со своей задачей

Ответ №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')
});
 

Комментарии:

1. Спасибо, но это подход без всякой функции. Имеет ли yup расширенную функцию?