reactjs - Formik villkorlig validering baserad på formulärvärden


Jag har ett något komplext formulär. Det har 3 grundläggande typer baserat på vilken typ av HTTP-förfrågan jag gör (POST_USER, PUT_USER, PUT_PASSWORD). Dessutom, i fallet med (POST_USER), behöver jag välja vilken typ av användare jag vill skapa. Mellan (BASIC & NON_BASIC).

Jag använder React, Formik och Yup för valideringen. Valideringen baserad på HTTP_REQUEST fungerar perfekt.

Problemet är att jag vill kontrollera baserat på formulärvärdena, och ValidationSchema från Formik som jag använder skickar dem inte som props. Så jag kan inte skicka ett argument till valideringsfunktionen som jag skickar till ValidationSchema. Här är funktionen som jag använder för validationSchema.

export const VALIDATION_RULES = (execMode: executionMode): any => {
  switch (execMode) {
    case executionMode.PUT_USER:
      return Yup.object().shape({
        username: Yup.string()
          .trim()
          .required('Name is required'),
        email: Yup.string()
          .email()
          .nullable(),
        groups: Yup.array().required('Group is required')
      });
    case executionMode.PUT_PASSWORD:
      return Yup.object().shape({
        password: Yup.string()
          .trim()
          .required('Password is required'),
        confirmPassword: Yup.string()
          .trim()
          .required('Password confirmation is required')
          .oneOf([Yup.ref('password')], 'Passwords do not match')
      });
    default:
      return Yup.object().shape({
        type: Yup.mixed()
          .oneOf([AuthenticationType.BASIC, AuthenticationType.NON_BASIC])
          .required('Authentication Type is required'),
        username: Yup.string()
          .trim()
          .required('Name is required'),
        email: Yup.string()
          .email()
          .nullable(),
        password: Yup.string()
          .trim()
          .required('Password is required'),
        confirmPassword: Yup.string()
          .trim()
          .required('Password confirmation is required')
          .oneOf([Yup.ref('password')], 'Passwords do not match'),
        groups: Yup.array().required('Group is required')
      });
  }
};

executionMode är en enkel Enum. Jag använder den både i funktionen ovan samt i komponenten själv:

enum executionMode {
  POST_USER = 'POST_USER',
  PUT_USER = 'PUT_USER',
  PUT_PASSWORD = 'PUT_PASSWORD'
}

export default executionMode;

Här är min komponent där jag anropar Formik själv:

      <Formik
        initialValues={this.getDefaultValues(Mode)}
        validationSchema={VALIDATION_RULES(Mode)}
        onSubmit={this.handleSubmit}
        render={({ isSubmitting, values, status }) => (
          <Form>
            ..Form Related Code. Doesn't have anything to do with validation
          </Form>
        )}
      />

PROBLEMET: Valideringen som beskrivs från koden ovan fungerar perfekt i alla scenarier utom för FORMULÄRET NON_BASIC POST_USER. Problemet där är att det inte tillåter mig att skapa användaren, eftersom valideringen för Lösenord och BekräftaLösenord fortfarande finns i själva validationSchema.

MÖJLIGA LÖSNINGAR: 1. Jag försökte använda validate från Formik, vilket skickar värdena som props, men logiken för att mappa felen till värdena måste skrivas om, vilket är ganska nedslående. Utöver det finns det mer anpassad kod som jag behöver skapa, som att hantera fel vid onChange och onBlur, vilket validateSchema hanterar perfekt på egen hand. 2. Jag försökte också använda when från yup. Det fungerar inte. Det godkänner valideringen, skickar formuläret och returnerar serverfelen.

Om du kan hjälpa mig skulle jag verkligen uppskatta det. Vänligen markera inte detta som en duplicering. Det är inte så enkelt som att använda when, och det finns väldigt begränsad dokumentation online om hur man använder validate och vad jag behöver göra med felkartan och hanteringen av ändringar vid händelser. Tack för din tid.