Привет! Это моя первая статья на Хабре и в ней я хочу рассказать о, первой мной написанной, библиотеке для работы с формами. Но сперва, давайте поговорим о том, как должна выглядеть идеальная библиотека для работы с формами.
-
Синтаксис будто создан для написания форм.
-
Формы просто дебажить и, еще проще, облагать их тестами.
-
Полная инкапсуляция логики конкретных инпутов.
-
Компоненты инпутов должны быть реюзабельными.
-
Конечная форма должна быть максимально абстрактной и легко читаемой.
А теперь, давайте посмотрим, как выглядит форма написанная с помощью 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/
Добавить комментарий