Привет, коллеги-разработчики пользовательского интерфейса!

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

Уххх. Мы могли бы проводить бессонные ночи, если бы выбрали пользовательскую историю с указанными выше требованиями. Также рассмотрите такую ​​большую форму с несколькими полями данных, для которых проверки будут динамически меняться. Мне бы очень хотелось пропустить эту пользовательскую историю, поскольку реализовать ее всегда сложно.

Хм, ну и что. Мы не можем оставить это в стороне, поскольку формы важнее всего реализовать. Следовательно, здесь на помощь приходит React Hooks.

Вау, мы нашли способ решить это уравнение. Но как мы можем использовать это в совершенстве. Давайте посмотрим, как обычно, на примере использования.

Пример использования:

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

Итак, начнем с написания файла конфигурации.

constants.FormValidations.js

export const formValidationConfigList = [
  {
    apiName: 'name',
    dataType: 'text',
    id: 'name',
    isRequired: true,
    hasError: false,
    label: 'Name',
  },
  {
    apiName: 'startDate',
    dataType: 'date',
    id: 'startDate',
    isRequired: true,
    hasError: false,
    label: 'Start Date',
  },
  {
    apiName: 'endDate',
    dataType: 'date',
    id: 'endDate',
    isRequired: false,
    hasError: false,
    errorMessage: '',   
    label: 'End Date',
    dependantAPIName: 'startDate;endDate',
    constraints: (modal) => {
      const hasError = modal.endDate && modal.startDate &&
              (new Date(modal.endDate) < new Date(modal.startDate))
      return {
        value: (hasError && '') || modal.endDate,
        variables: {
          errorMessage: (hasError && 
                'End date cannot be greater than Start date') || '',
          hasError,
        },
      }
    },
  },
]

Здесь name и startDate apis гораздо более знакомы всем, так как это обычная конфигурация, которую мы пишем для формы. Но что с endDate. endDate api выглядит так же, как startDate и name, но есть два дополнительных ключа, которые делают его уникальным по сравнению с двумя другими api

dependantAPIName - Конфигурация, которая сообщает слушателю, кем бы он ни был, что этот api зависит от apiNames, указанных в этом ключе (который разделен запятыми). Здесь endDate зависит от startDate и от самого себя. (Звучит странно: Р)

constraints - Конфигурация, которая сообщает слушателю, кем бы он ни был, что этот API должен заставить слушателя выполнять функцию, определенную всякий раз, когда apis зависимого APIName в модальном окне изменяется как таковой, эта функция изменяет конфигурацию во время выполнения, таким образом предоставляя новые значения API на модальный, на котором записаны ограничения

Отсюда доказано…. Ооо… то, что мы увидели, - всего лишь теоретическая часть. Давайте посмотрим, как практически мы можем этого добиться. Впрочем, достаточно просто чашки кофе ☕️ 😜

А теперь и наш герой - React Hooks.

Давайте разберемся с этой ситуацией шаг за шагом. Сначала мы создаем простой компонент, который выполняет итерацию по вышеуказанной конфигурации и создает компонент ввода для каждого элемента в конфигурации и при изменении входных значений обновляет modalData с помощью редукторов - как useReducer в React Hooks

Приведенный выше фрагмент js - это образец для рисования входных компонентов в соответствии с конфигурацией и, следовательно, обновления модального окна на ходу.

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

Установка ограничений

Вы можете видеть, что произошли изменения в методе handleChange, и в состояние добавлена ​​новая переменная, которая называется validationsConfigList (которая раньше была статической, как в предыдущем примере, но теперь она должна быть динамической).

Давайте больше сконцентрируемся на методе handleChange (новые дополнения, кроме предыдущего примера)

const modifiedConfigList = validationsConfigList.map(
    (eachConfigInList) => {
      const eachConfig = {
        ...eachConfigInList
      }
      if(eachConfig.dependantAPIName && 
        ((apiName && 
          eachConfig.dependantAPIName.indexOf(apiName) >= 0) 
          || !apiName) {
          // we found out is the current api in the config list is dependant on the modified apiName from the form
        const returnedConstraints = eachConfig.constraints(modalData)
        const {variables, value} = returnedConstraints
        modalData[eachConfig.apiName] = value
        eachConfig = Object.assign(eachConfig, variables)
    }
    return eachConfig                                                
})
  1. Сначала мы перебираем каждую конфигурацию в списке конфигураций.
  2. Клонировать конфигурацию, которая является текущей областью видимости при зацикливании (поскольку нам не нужно изменять конфигурацию, которая находится в состоянии)
  3. Проверьте, совпадает ли имя зависимого APIName, указанное в конфигурации, с apiName, которое подвергается модификации.
  4. Выполните функцию ограничений, которая присутствует в конфигурации, передав измененные данные modalData и зафиксируйте возвращаемое значение.
  5. Получите переменные и значение из возвращенного объекта при выполнении функции ограничений
  6. Используйте значение, чтобы изменить modalData, и переменные, чтобы изменить параметры конфигурации.

Следовательно, используйте этот modifiedConfigList для установки состояния и отправки как validationsConfigList, чтобы изменять конфигурации при запуске (и, конечно, теперь он динамический - не так ли?!?!?!)

Давайте посмотрим, как мы можем запустить этот пример (конечно, практические знания более необходимы, чем теоретические)

Красиво, не правда ли… ..?!?!?!

Следовательно, Доказано… .. Тадааааа…. Лайки и комментарии очень ценятся :)