Эффективная работа с формами с помощью react-redux-hook-form

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

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

  1. Синтаксис будто создан для написания форм.

  2. Формы просто дебажить и, еще проще, облагать их тестами.

  3. Полная инкапсуляция логики конкретных инпутов.

  4. Компоненты инпутов должны быть реюзабельными.

  5. Конечная форма должна быть максимально абстрактной и легко читаемой.

А теперь, давайте посмотрим, как выглядит форма написанная с помощью react-redux-hook-form.

export const Login:FC = memo( () => {
  const form = useForm({name: 'login'})

  return (
    <WrapperForm form={form} onSubmit={(data:ILogin) => {User.options.login(data)}}>
      <InputTitleStyled>Номер телефона</InputTitleStyled>
      <PhoneInput name={'username'} required/>

      <InputTitleStyled>Пароль</InputTitleStyled>
      <PasswordInput name={'password'} required/>

      <SubmitButton text={'Авторизироваться'}/>
    </WrapperForm>
  )
})

Здесь мы используем хук useForm и обертку для формы WrapperForm.

useForm - хук для инициализации формы, принимает name и возвращает объект с методами для работы с формой. form.reset, form.changeDataField, form.changeIsValidateField, form.changeMessageErrorField, form.useFieldSelector. Полагаю, не имеет смысла описывать принцип работы каждого метода.

WrapperForm - обертка формы в которую обязательно должна быть обернута форма. Принимает параметры: onChange, initialValue, onSubmit.

Теперь давайте посмотрим, как создаются инпуты.

interface IEmail {
  name: string;
  required?: boolean;
}

export const EmailInput: FC<IEmail> = (props) => {
  const {useData, useIsValidate, useIsTouch, useMessageError} = useField({
    name: props.name,
    isRequired: props.required,
    validateFunction: (value:string) => validate(value).string().max(30).email(),
  })

  const [data, changeData] = useData()
  const [isValidate, ] = useIsValidate()
  const [isTouch, ] = useIsTouch()
  const [messageError, ] = useMessageError()

  return (
    <>
      <EmailInputStyled
        type={"email"} 
				value={data}
        onChange={(e:any)=> {changeData(e.target.value)}}
        isValidate={isValidate || !isTouch}
        id={props.name}
      />
      {!isValidate && isTouch &&
        <ErrorTitleStyled className={'error'}>
          {messageError}
        </ErrorTitleStyled>
      }
    </>
  )
};

Здесь мы используем useField. useField - инициализирует поле и из него достаются хуки для работы с полем. useData, useIsValidate, useIsTouch, useMessageError, работают по принципу useState. Validate/IsTouch/MessageError - автоматически обрабатываются, но если вы хотите самостоятельно обрабатывать данные поля, библиотека позволит вам это сделать. Для того, чтобы отменить автоматическую обработку, необходимо в useField передать isDisableAuto: true.

Параметры useField: name, initialValue, isRequired, isDisableAuto, messageError, isTouch, isValidate, validateFunction.

name: название поля. Все поля должны быть уникальными.

initialValue: стандартное значение. Стоит использовать для того, чтобы явно указать, в каком формате будут храниться данные в данном инпуте. Перебивается initialValues с формы.

Теперь давайте посмотрим, как создать кнопку, для данной формы.

interface ISubmitButton {
  text: string;
  className?: string;
}

export const SubmitButton: FC<ISubmitButton> = (props) => {
  const formName = useContext(formNameContext)
  const isValidForm = useIsValidForm(formName)
  const onSubmit = useContext(onSubmitContext)

  const onClick = () => {
    if(isValidForm){
      onSubmitForm(formName, onSubmit)
    }
  }
  return (
    <SubmitButtonStyled className={props.className} isValidForm={isValidForm} onClick={onClick}>
      {props.text}
    </SubmitButtonStyled>
  )
};

В данном примере мы достаем из контекста formName и onSubmit.

Также мы используем useIsValidateForm хук, в которым передаем имя формы.

Так-как мы используем redux. То мы можем использовать данные формы в других местах.

Например:

const search = useFieldSelector({formName: 'searchForm', fieldName: 'search'})

Подключение react-redux-hook-form.

Сперва установим: npm i react-redux-hook-form.

Затем надо модифицировать стор.

1) Подключим formControllerReducer.

import { formControllerReducer } from 'react-redux-hook-form';

const combinedReducer = combineReducers({
  formController: formControllerReducer, // подключение formControllerReducer
  user: userReducer,
  contact: contactReducer,
});

2) Запишем функцию getState в window.

window.getState = () => store.getState()

В общем-то это все что нужно знать для того чтобы использовать react-redux-hook-form.

Так как мы используем redux, мы можем дебажить форму через redux-devtools(расширения гугл хрома).

Думаю, еще стоит уделить пару строчек себе. У меня не так много коммерческого опыта, всего лишь 1.5 года. да и то треть из этого опыта это работа на бэке. Так что жду предложению по тому, как можно улучшить данную библиотеку :)

Источник: https://habr.com/ru/post/669362/


Интересные статьи

Интересные статьи

Здравствуйте, Хабровчане! Сегодня возвращаемся к ещё одной доброночной теме -  бэкапу отечественной виртуализации. Возвращаемся с конкретным решением вопроса, в частности – представляем российску...
Любой алгоритмический процесс может быть автоматизирован, обычно для автоматизации рутинных задач пишутся скрипты, которые принимают определённые параметры, делают определённые действия, и возвращают ...
Группа М.Видео-Эльдорадо в начале 2021 года представила стратегию Hacking Retail. За 5 лет мы планируем увеличить общий товарооборот вдвое до 1 млрд рублей и в три раза расширить ассо...
В Челябинске проходят митапы системных администраторов Sysadminka, и на последнем из них я делал доклад о нашем решении для работы приложений на 1С-Битрикс в Kubernetes. Битрикс, Kubernetes, Сep...
Несколько месяцев назад меня вдруг поразила мысль, что я понятия не имею о принципах работы компьютерного железа. Я до сих пор не знаю, как работают современные компьютеры. Я прочитал книгу ...