Давным-давно, не так давно, я создал свое первое приложение на React. Одним из моих компонентов была форма, которую пользователю предлагается заполнить после регистрации.

Изначально этот пост был предназначен для того, чтобы дать вам краткое руководство по созданию интерактивных форм в React с помощью ссылок. Однако существует множество постов и руководств по этой теме. Я предполагаю, что вы немного знаете о ссылках и, возможно, уже использовали их в своих компонентах. Я здесь, чтобы помочь тем из вас, кто, как и я, использовал Semantic UI React для добавления стиля в свое приложение React и внезапно понял, что добавление ссылки традиционным способом, описанным в документации, возвращает null.

Так или иначе, вот как выглядел мой код:

myRef = createRef()
...
<Form.Input
ref={this.myRef}
id='first_name'
label='First Name'
placeholder='Enter your first name'
/>

И вот что произошло, когда я добавил отладчик в свою функцию рендеринга, чтобы взглянуть на myRef:

Я попробовал несколько разных вещей и быстро понял, что самый простой и быстрый выход из этого - использовать простой HTML для моей формы и стилизовать ее с помощью CSS, затем прикрепить ссылку к моему тегу ‹input› и продолжить свою жизнь. Я мог бы, наверное, начать с чего-то вроде этого и начать с этого:

<input ref={this.firstName} type=’text’ />

Но это было похоже на простой выход и обходной путь, а не решение. Кроме того, мое сердце было настроено на Semantic UI для моей CSS-структуры, и я хотел, чтобы она была единообразной на протяжении всего проекта. Не говоря уже о том, что я был рад немного покопаться и найти решение, а затем жить, чтобы написать об этом в блоге!

Давайте приступим.

Вот моя форма:

Обратите внимание, что это не полная форма, используемая в моем приложении. Я обрезал его, чтобы продемонстрировать рефакторинг. Я хотел, чтобы у него были разные типы ввода (у нас есть ввод, текстовая область и раскрывающийся список), но достаточно компактный, чтобы не отвлекать от моей основной мысли. Я также удалил функции, отвечающие за изменение объекта данных, который затем отправляется на мой сервер Rails. Я обязательно дам ссылку на отдельный пост, чтобы дать вам несколько советов по этому поводу, как только я закончу его полировать.

Вот суть, показывающая большую часть исходного компонента формы:

Как видите, наша форма требует некоторой работы с мышью, что не идеально для хорошего пользовательского интерфейса. Пришло время сделать его лучше, переместив курсор в следующее поле после того, как пользователь завершит заполнение текущего поля и нажмет Enter, а также отправит форму одним нажатием клавиши (старый добрый «Enter» в нашем случае). Больше никаких щелчков и движений мыши.

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

Вот готовый код:

И вот что я сделал шаг за шагом:

  1. Импортировано {createRef} из «react» - см. строку 1.
  2. Импортировано {Ref} из "semantic-ui-react" (он обернет наш компонент Semantic UI и позволит нам добавить к нему ссылку) - см. Строку 3
  3. Создал ссылки для всех моих входных данных - см. строки 14–19.
  4. Добавлен метод жизненного цикла componentDidMount (), поэтому курсор будет focus () на нашем первом поле в форме - см. строки 23–25.
  5. Обернули все подкомпоненты myForm в компонент Ref и к каждому добавили свойство innerRef (оно должно называться innerRef!) - см. строки 121, 134 , 148, 160, 174, 190.
  6. Во все подкомпоненты моей формы добавлено событие onKeyUp.
  7. Создан прослушиватель событий, который срабатывает, когда пользователь нажимает клавишу «Ввод», и focus () перемещает курсор в следующее поле формы.

Вам может быть интересно, как я придумал

this.firstNameRef.current.lastChild.firstChild.focus()

Semantic UI React обеспечивает определенный уровень абстракции, заключающий коллекцию элементов в один элемент Input, и поскольку наша ссылка (в данном случае свойство innerRef) прикрепляется ко всему «пакету» (также известному как «Наш вход»), у нас автоматически нет прямого доступ к тегу ‹input›, вложенному в компонент ввода семантического пользовательского интерфейса. Чтобы добраться до него, потребовалось небольшое рассечение. Не бойтесь, ваш старый добрый друг «отладчик» и разработчик Chrome - это все, что вам нужно. Я рекомендую установить отладчик в ваш метод рендеринга и взглянуть на все ваши ссылки, помня, что вы хотите попасть в теги ‹input›, ‹textarea› и т. Д. Вот пример:

Как видите, я внимательно смотрю на свое свойство this.firstNameRef, в частности на его свойство current, а затем проверяю элемент. Вот откуда я знаю, что мой ‹input› вложен в lastChild (альтернативно lastChildElement) моего main ‹div› (где был размещен this.firstNameRef). Вложенный ‹div› имеет один дочерний элемент - это ‹input›, который мы искали все время и на который мы хотим переместить курсор (используя f ocus ()).

Вот и все!

Надеюсь, это будет полезно. Не стесняйтесь обращаться к нам, если у вас есть какие-либо вопросы или предложения. Я новичок, который любит учиться и помогать другим учиться.