Javascript-форум (https://javascript.ru/forum/)
-   Библиотеки/Тулкиты/Фреймворки (https://javascript.ru/forum/library-toolkit-framework/)
-   -   Как я могу проверить только одно поле из формы используя Yup? (https://javascript.ru/forum/library-toolkit-framework/84272-kak-ya-mogu-proverit-tolko-odno-pole-iz-formy-ispolzuya-yup.html)

CryNet 26.07.2022 09:36

Как я могу проверить только одно поле из формы используя Yup?
 
Схема выглядит так:

const ValidationScheme = Yup.object().shape({
  email: Yup.string()
    .required('Required')
    .email('Invalid email address'),
  password: Yup.string()
    .required('Required'),
  code: Yup.number()
    .integer()
    .positive()
    .typeError('You must specify a number')
    .required('Required'),
});


При клике на кнопку мне нужно провалидировать только поле "email" из формы. Удалить остальные поля из схемы я не могу, они мне нужны в другой логике (сабмит формы). Как мне это сделать?

P.S это всё работает на Реакте

Nexus 26.07.2022 14:31

Пробовали так?
const emailFieldValidationScheme = Yup.string()
    .required('Required')
    .email('Invalid email address');

const ValidationScheme = Yup.object().shape({
  email: emailFieldValidationScheme,
  password: Yup.string()
    .required('Required'),
  code: Yup.number()
    .integer()
    .positive()
    .typeError('You must specify a number')
    .required('Required'),
});

emailFieldValidationScheme.validateSync('test');

CryNet 26.07.2022 14:35

Цитата:

Сообщение от Nexus (Сообщение 546849)
Пробовали так?

В консоли ошибка, но сам инпут не подсвечивается, мол, он неправильно заполненный:
https://i.ibb.co/T2w9VPX/Screenshot-20220726-143353.png

Nexus 26.07.2022 14:38

CryNet, ну так перехватите эти ошибки и отобразите для пользователя.

CryNet 26.07.2022 16:19

Цитата:

Сообщение от Nexus (Сообщение 546851)
CryNet, ну так перехватите эти ошибки и отобразите для пользователя.

Та у меня есть костыль для этого:
if (rEmail.test(email)) {
      clearErrors('email');
    } else {
      return setError('email', { message: 'Invalid email address' });
    }

Но я бы хотел, чтобы это полностью обработал Yup. Но ваш костыль получше моего.

Nexus 26.07.2022 16:48

Цитата:

Сообщение от CryNet
Но я бы хотел, чтобы это полностью обработал Yup.

Yup только проверяет соответствуют ли передаваемые данные созданной вами схеме, всем остальным, в том числе отображением уведомлений об ошибках, занимается "кто-то другой" (скорее всего, какая-то библиотека для построения форм).

CryNet 26.07.2022 17:02

Цитата:

Сообщение от Nexus (Сообщение 546853)
Yup только проверяет соответствуют ли передаваемые данные созданной вами схеме, всем остальным, в том числе отображением уведомлений об ошибках, занимается "кто-то другой" (скорее всего, какая-то библиотека для построения форм).

Да, правильно. У меня react-hook-form для форм юзается.

const {
    handleSubmit,
    control,
    formState: { errors }, // !important
    setError,
    register,
    clearErrors,
    getValues,
  } = useForm<ILoginForm>({
    resolver: yupResolver(ValidationScheme),
    defaultValues: {
      email: '',
      password: '',
      code: '',
    },
  });

Провозившись с Yum-ом забыл расписать нормально. При клике на Сабмит ошибка из Yum-а попадает в react-hook-form: resolver: yupResolver(ValidationScheme). Видимо таки придётся совместить ваше решение с моим. Я почему-то надеялся, что можно как-то более лаконично решить это. В любом случае -- спасибо вам за идею.

Nexus 26.07.2022 22:29

CryNet, зачем вам понадобилось проверять одно единственное поле на корректность введенных пользователем данных?

Мне кажется, что вы решаете несуществующую проблему, либо существующую, но не тем способом.

CryNet 27.07.2022 09:17

Цитата:

Сообщение от Nexus (Сообщение 546860)
CryNet, зачем вам понадобилось проверять одно единственное поле на корректность введенных пользователем данных?

Мне кажется, что вы решаете несуществующую проблему, либо существующую, но не тем способом.

Сейчас распишу весь флоу. У меня есть форма:
- email
- password
- 2FA
И две кнопки:
- Get 2FA
- Submit
Флоу такой:
- юзер заполнил поля email и password и кликает на кнопку Get 2FA (вот тут мне нужно проверить это единственное поле)
- юзер вводит 2FA и кликает на Сабмит (тут проверяется всё остальное)

Nexus 27.07.2022 18:02

CryNet, я бы сделал как-то так только через class component:

https://codesandbox.io/s/form-exampl...c/LoginForm.js

import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as Yup from "yup";

export default function LoginForm() {
  const [tokenWasRequested, saveTokenWasRequested] = useState(false);

  const validationScheme = Yup.object().shape({
    email: Yup.string().required("Required").email("Invalid email address"),
    ...(tokenWasRequested
      ? {
          password: Yup.string().required("Required"),
          code: Yup.number()
            .integer()
            .positive()
            .typeError("You must specify a number")
            .required("Required")
        }
      : {})
  });

  const {
    register,
    handleSubmit,
    formState: { errors }
  } = useForm({
    mode: "all",
    criteriaMode: "all",
    resolver: yupResolver(validationScheme)
  });

  const onSubmit = (data) => {
    if (!tokenWasRequested) {
      saveTokenWasRequested(true);

      return;
    }

    console.log(data);
  };

  const fields = [
    {
      type: "email",
      name: "email",
      label: "Email",
      props: {
        readOnly: tokenWasRequested
      }
    }
  ];

  if (tokenWasRequested) {
    fields.push(
      {
        type: "password",
        name: "password",
        label: "Password"
      },
      {
        type: "text",
        name: "code",
        label: "2FA token"
      }
    );
  }

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {fields.map((field) => {
        const errorMessage = errors?.[field.name]?.message;

        return (
          <div
            key={`form-field--${field.type}-${field.name}`}
            className="field-wrapper"
          >
            <input
              {...(field.props ?? {})}
              type={field.type}
              placeholder={field.label}
              className={errorMessage ? "invalid" : undefined}
              {...register(field.name)}
            />
            {errorMessage ? (
              <div className="error-message">{errorMessage}</div>
            ) : null}
          </div>
        );
      })}
      <div className="form-controls">
        <button type="submit">
          {tokenWasRequested ? "Login" : "Get 2FA token"}
        </button>

        {tokenWasRequested ? (
          <button
            type="button"
            onClick={() => {
              saveTokenWasRequested(false);
            }}
          >
            Request another 2FA token
          </button>
        ) : null}
      </div>
    </form>
  );
}

CryNet 28.07.2022 09:15

Цитата:

Сообщение от Nexus (Сообщение 546881)
я бы сделал как-то так только через class component

О, спасибо. А почему классы?

Nexus 28.07.2022 16:13

CryNet, текущий компонент, имхо, плохо читаем.
В классе данные и "действия" можно раскидать по разным методам улучшив его читаемость.

CryNet 28.07.2022 18:07

Цитата:

Сообщение от Nexus (Сообщение 546910)
CryNet, текущий компонент, имхо, плохо читаем.
В классе данные и "действия" можно раскидать по разным методам улучшив его читаемость.

Разве смешивают классы и компоненты? Никогда просто такого не видел, если это не старый проект

Nexus 28.07.2022 19:28

Цитата:

Сообщение от CryNet
Разве смешивают классы и компоненты?

Есть functional component, есть class component. И первое, и второе является компонентом.

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

Возможно кто-то из здесь присутствующих более опытных коллег поделится своим опытом и мыслями по этому поводу.

CryNet 29.07.2022 09:17

Цитата:

Сообщение от Nexus (Сообщение 546920)
Есть functional component, есть class component. И первое, и второе является компонентом.

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

Возможно кто-то из здесь присутствующих более опытных коллег поделится своим опытом и мыслями по этому поводу.

Ага, я понял. Спасибо. Ну мы на работе юзаем только функциональные компоненты.

rockzzstud 24.11.2022 14:37

CryNet, зачем вам понадобилось проверять одно единственное поле на корректность введенных пользователем данных?

panoramacharter.ltd

router admin login


Часовой пояс GMT +3, время: 16:34.