Close

26 июня, 2021

Использование форм в React

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

Мы собираемся познакомится с такими вопросами:

Как создавать формы React без установки каких-либо библиотек

Два стиля входных данных в формах React

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

Когда использовать контролируемый или неконтролируемый ввод

Простой способ получить значения из неконтролируемого ввода

Как создавать формы с помощью Plain React

Давайте начнем. Мы собираемся создать простую контактную форму. Рассмотрим автономный компонент ContactForm который отображает форму:

JavaScript
function ContactForm() {
return (
<form>
<div>
<label htmlFor=»name»>Name</label>
<input id=»name» type=»text» />
</div>
<div>
<label htmlFor=»email»>Email</label>
<input id=»email» type=»email» />
</div>
<div>
<label htmlFor=»message»>Message</label>
<textarea id=»message» />
</div>
<button type=»submit»>Submit</button>
</form>
);
}

12345678910111213141516171819 function ContactForm() {  return (    <form>      <div>        <label htmlFor=»name»>Name</label>        <input id=»name» type=»text» />      </div>      <div>        <label htmlFor=»email»>Email</label>        <input id=»email» type=»email» />      </div>      <div>        <label htmlFor=»message»>Message</label>        <textarea id=»message» />      </div>      <button type=»submit»>Submit</button>    </form>  );}

Вам не нужно устанавливать дополнительных библиотек. React имеет встроенную поддержку форм, потому что HTML и DOM имеют встроенную поддержку форм. В конце концов, React отрисовывает узлы DOM.

Фактически, для малых форм вам, вероятно, вообще не нужна библиотека форм. Что-то вроде Formik или response-hook-form будет излишним, если вам нужна простая форма.

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

React Forms против HTML-форм

Если вы работали с формами в обычном HTML, многое из этого, вероятно, покажется вам знакомым. Там есть тег form, и label для ввода, как если бы вы писали в HTML.

У каждой label есть свойство htmlFor которое соответствует значению id на входе. (Есть одно отличие: React использует htmlFor вместо for.)

Если вы не знакомы с HTML, просто знайте, что React не придумал ничего нового! Совйства в React является довольно ограничены, и работа формы заимствована из HTML и DOM.

Два типа ввода: контролируемый и неконтролируемый

Ввод данных в React может быть одного из двух типов: контролируемый и неконтролируемый. Неконтролируемый ввод проще. Это самый близкий к обычному HTML-вводу. React размещает его на странице, а браузер отслеживает все остальное. Когда вам нужно получить доступ к входному значению, React предоставляет способ сделать это. Неконтролируемые вводы требуют меньше кода, но затрудняют выполнение определенных действий.

С управляемым вводом ВЫ явно контролируете значение, отображаемое на вводе. Вы должны написать код, чтобы реагировать на нажатия клавиш, где-то хранить текущее значение и передавать это значение обратно на ввод для отображения. Это цикл обратной связи с вашим кодом. Их подключение требует больше ручной работы, но они обеспечивают максимальный контроль.

Давайте посмотрим на эти два стиля на практике, применив их к нашей контактной форме.

Контролируемый ввод

С управляемым вводом вы пишете код для явного управления значением. Вам нужно будет создать состояние для его хранения, обновить это состояние при изменении значения и явно указать входным данным, какое значение отображать.

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

JavaScript
function ContactForm() {
const [name, setName] = React.useState(»);
const [email, setEmail] = React.useState(»);
const [message, setMessage] = React.useState(»);

function handleSubmit(event) {
event.preventDefault();
console.log(‘name:’, name);
console.log(’email:’, email);
console.log(‘message:’, message);
}

return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor=»name»>Name</label>
<input
id=»name»
type=»text»
value={name}
onChange={(e) => setName(e.target.value)}
/>
</div>
<div>
<label htmlFor=»email»>Email</label>
<input
id=»email»
type=»email»
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</div>
<div>
<label htmlFor=»message»>Message</label>
<textarea
id=»message»
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
</div>
<button type=»submit»>Submit</button>
</form>
);
}

1234567891011121314151617181920212223242526272829303132333435363738394041424344 function ContactForm() {  const [name, setName] = React.useState(»);  const [email, setEmail] = React.useState(»);  const [message, setMessage] = React.useState(»);   function handleSubmit(event) {    event.preventDefault();    console.log(‘name:’, name);    console.log(’email:’, email);    console.log(‘message:’, message);  }   return (    <form onSubmit={handleSubmit}>      <div>        <label htmlFor=»name»>Name</label>        <input          id=»name»          type=»text»          value={name}          onChange={(e) => setName(e.target.value)}        />      </div>      <div>        <label htmlFor=»email»>Email</label>        <input          id=»email»          type=»email»          value={email}          onChange={(e) => setEmail(e.target.value)}        />      </div>      <div>        <label htmlFor=»message»>Message</label>        <textarea          id=»message»          value={message}          onChange={(e) => setMessage(e.target.value)}        />      </div>      <button type=»submit»>Submit</button>    </form>  );}

Мы добавили 3 вызова useState для создания 3 переменных для хранения значений входных данных. Они изначально пустые. Каждый input получил пару новых реквизитов.

Value сообщает, что отображать. Здесь мы передаем значение из соответствующей переменной состояния.

onChange является функцией и вызывается, когда пользователь изменяет ввод. Он получает событие (обычно называемое e или event, но вы можете назвать его как угодно), и мы берем текущее значение ввода ( e.target.value) и сохраняем его в состоянии.

При каждом нажатии клавиши вызывается наш onChange, и мы явно устанавливаем setWhatever, который повторно отображает всю ContactForm с новым значением. Это означает, что при каждом нажатии клавиши компонент будет повторно отображать всю форму.

Для малых форм это нормально. И это на самом деле нормально. Визуализация выполняется быстро. Рендеринг 3, 5 или 10 вводов при каждом нажатии клавиш не замедлит работу приложения заметно.

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

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

Альтернатива…

Неконтролируемый ввод

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

Неконтролируемый ввод управляет своим значением. Как и в случае с простой HTML-формой, значение сохраняется во входном узле DOM. Нет необходимости отслеживать это вручную.

В первом примере кода на этой странице все вводы были неконтролируемыми, потому что мы не передавали свойство value, которое сообщала бы нам, какое значение отображать.

Но если мы не отслеживаем значение … как мы можем определить, каково оно? Вот где пригодятся «ref».

Что такое «ref»?

React берет ваш JSX и создает фактическую модель DOM, которую отображает браузер. Ref связывает эти два представления вместе, позволяя вашему компоненту React получить доступ к узлам DOM, которые его представляют. Ref содержит ссылку на узел DOM.

Вот почему это важно: JSX, который вы пишете, — это просто описание страницы, которую вы хотите создать. Что вам действительно нужно, так это базовая модель DOM input, чтобы вы могли извлечь значение.

Итак, чтобы получить значение из неконтролируемого ввода, вам нужна ссылка на него, которую мы получаем, назначая свойству ref. Затем вы можете прочитать значение при отправке формы (или, когда захотите!).

Давайте добавим ссылки в input нашей контактной формы, основываясь на примере нашей «простой формы»:

JavaScript
function ContactForm() {
const nameRef = React.useRef();
const emailRef = React.useRef();
const messageRef = React.useRef();

return (
<form>
<div>
<label htmlFor=»name»>Name</label>
<input
id=»name»
type=»text»
ref={nameRef}
/>
</div>
<div>
<label htmlFor=»email»>Email</label>
<input
id=»email»
type=»email»
ref={emailRef}
/>
</div>
<div>
<label htmlFor=»message»>Message</label>
<textarea
id=»message»
ref={messageRef}
/>
</div>
<button type=»submit»>Submit</button>
</form>
);
}

12345678910111213141516171819202122232425262728293031323334 function ContactForm() {  const nameRef = React.useRef();  const emailRef = React.useRef();  const messageRef = React.useRef();   return (    <form>      <div>        <label htmlFor=»name»>Name</label>        <input          id=»name»          type=»text»          ref={nameRef}        />      </div>      <div>        <label htmlFor=»email»>Email</label>        <input          id=»email»          type=»email»          ref={emailRef}        />      </div>      <div>        <label htmlFor=»message»>Message</label>        <textarea          id=»message»          ref={messageRef}        />      </div>      <button type=»submit»>Submit</button>    </form>  );}

Здесь мы сделали пару вещей:

создал 3 ссылки с помощью хука useRef

привязали ссылки к входным данным с помощью свойства ref

Когда компонент отрисовывается впервые, React настроит ссылки. nameRef.current будет ссылаться на name узела DOM, emailRef.current будет ссылаться на входное сообщение электронной почты и так далее.

Эти ссылки содержат те же значения, что и те, которые вы получили бы, если бы запустили document.querySelector(‘input[id=name]‘) в консоли браузера. Это необработанная входная нода браузера; React просто возвращает ее вам.

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

Мы можем создать функцию для обработки отправки формы и распечатать значения:

JavaScript
function ContactForm() {
const nameRef = React.useRef();
const emailRef = React.useRef();
const messageRef = React.useRef();

function handleSubmit(event) {
event.preventDefault();
console.log(‘name:’, nameRef.current.value);
console.log(’email:’, emailRef.current.value);
console.log(‘message:’, messageRef.current.value);
}

return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor=»name»>Name</label>
<input
id=»name»
type=»text»
ref={nameRef}
/>
</div>
<div>
<label htmlFor=»email»>Email</label>
<input
id=»email»
type=»email»
ref={emailRef}
/>
</div>
<div>
<label htmlFor=»message»>Message</label>
<textarea
id=»message»
ref={messageRef}
/>
</div>
<button type=»submit»>Submit</button>
</form>
);
}

1234567891011121314151617181920212223242526272829303132333435363738394041 function ContactForm() {  const nameRef = React.useRef();  const emailRef = React.useRef();  const messageRef = React.useRef();   function handleSubmit(event) {    event.preventDefault();    console.log(‘name:’, nameRef.current.value);    console.log(’email:’, emailRef.current.value);    console.log(‘message:’, messageRef.current.value);  }   return (    <form onSubmit={handleSubmit}>      <div>        <label htmlFor=»name»>Name</label>        <input          id=»name»          type=»text»          ref={nameRef}        />      </div>      <div>        <label htmlFor=»email»>Email</label>        <input          id=»email»          type=»email»          ref={emailRef}        />      </div>      <div>        <label htmlFor=»message»>Message</label>        <textarea          id=»message»          ref={messageRef}        />      </div>      <button type=»submit»>Submit</button>    </form>  );}

Функция handleSubmit может делать с этими значениями все, что вам нужно: проверять их, асинхронно отправлять их на сервер и т. д. Обратите внимание, на вызов event.preventDefault(). Без этого отправка формы обновит страницу.

Контролируемое или неконтролируемое: что использовать?

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

(Возможно, вы слышали, что контролируемый ввод — это «лучшая практика», что, конечно, подразумевает, что неконтролируемый ввод — нет! Я вернусь к этому ближе к концу.)

Когда и зачем использовать контролируемые вводы

Из двух стилей контролируемый ввод является более «реактивным» способом выполнения действий, когда пользовательский интерфейс отражает состояние. Изменяя состояние, вы меняете пользовательский интерфейс. Если вы не измените состояние, пользовательский интерфейс останется прежним.

Это делает контролируемые входы идеальными для таких вещей, как:

Мгновенная проверка формы при каждом нажатии клавиши: полезно, если вы хотите, например, сделать кнопку «Отправить» отключенной, пока все значения не станут валидными.

Обработка форматированного ввода, например поля номера кредитной карты, или предотвращение ввода определенных символов.

Синхронизация нескольких вводов друг с другом, если они основаны на одних и тех же данных

Решение остается за вами, дорогой разработчик. Хотите игнорировать какой-то странный символ, введенный пользователем? Легко, просто убери это.

React JS. Основы

Изучите основы ReactJS на практическом примере по созданию учебного веб-приложения

Получить курс сейчас!

JavaScript
function EmailField() {
const [email, setEmail] = useState(»);

const handleChange = e => {
// no exclamations allowed!
setEmail(e.target.value.replace(/!/g, »));
}

return (
<div>
<label htmlFor=»email»>Email address</label>
<input
id=»email»
value={email}
onChange={handleChange}
/>
</div>
);
}

12345678910111213141516171819 function EmailField() {  const [email, setEmail] = useState(»);   const handleChange = e => {    // no exclamations allowed!    setEmail(e.target.value.replace(/!/g, »));  }   return (    <div>      <label htmlFor=»email»>Email address</label>      <input        id=»email»        value={email}        onChange={handleChange}      />    </div>  );}

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

Контролируемые вводы более сложны

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

JavaScript
function MultipleInputs() {
const [values, setValues] = useState({
email: »,
name: »
});

const handleChange = e => {
setValues(oldValues => ({
…oldValues,
[e.target.name]: e.target.value
}));
}

return (
<>
<div>
<label htmlFor=»email»>Email address</label>
<input
id=»email»
name=»email»
value={values.email}
onChange={handleChange}
/>
</div>
<div>
<label htmlFor=»name»>Full Name</label>
<input
id=»name»
name=»name»
value={values.name}
onChange={handleChange}
/>
</div>
</>
);
}

123456789101112131415161718192021222324252627282930313233343536 function MultipleInputs() {  const [values, setValues] = useState({    email: »,    name: »  });   const handleChange = e => {    setValues(oldValues => ({      …oldValues,      [e.target.name]: e.target.value    }));  }   return (    <>      <div>        <label htmlFor=»email»>Email address</label>        <input          id=»email»          name=»email»          value={values.email}          onChange={handleChange}        />      </div>      <div>        <label htmlFor=»name»>Full Name</label>        <input          id=»name»          name=»name»          value={values.name}          onChange={handleChange}        />      </div>    </>  );}

Такой шаблонный макет — одна из причин, по которой библиотеки форм React так популярны, но опять же, если у вас есть 2 или 3 ввода на странице, я бы сказал, что экономия нескольких строк не стоит добавления библиотеки форм.

Повторный рендеринг контролируемых вводов при каждом нажатии клавиши

Каждый раз, когда вы нажимаете клавишу, React вызывает функцию в свойстве onChange, которая устанавливает состояние. Установка состояния приводит к повторному рендерингу компонента и его дочерних элементов (если они еще не оптимизированы с помощью React.memo или PureComponent).

В основном это нормально. Визуализация выполняется быстро. Для малых и средних форм вы, вероятно, даже не заметите. И дело не в том, что рендеринг ничтожно маленького размера input происходит медленно… но это может быть проблемой в целом.

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

Если вы начинаете подозревать эту проблему в своем приложении, запустите Profiler в React Developer Tools и выполните измерения, нажимая некоторые клавиши. Он скажет вам, какие компоненты замедляют работу.

Неконтролируемые входные данные не обрабатываются повторно

Важным аргументом в пользу использования неконтролируемого ввода является то, что браузер позаботится обо всем. Вам не нужно обновлять состояние, а это значит, что вам не нужно повторно рендерить. Каждое нажатие клавиши обходит React и переходит прямо в браузер.

Ввод буквы ‘a’ в форму с 300 входами приведет к повторному рендерингу ровно ноль раз, что означает, что React может сидеть сложа руки и ничего не делать. Ничего не делать очень эффективно.

У неконтролируемых вводов может быть еще меньше шаблонов!

Ранее мы рассмотрели, как создавать ссылки на входные данные, используя useRef и передавать их в качестве свойства ref.

Фактически вы можете пойти дальше и полностью удалить ссылки, воспользовавшись тем фактом, что форма знает о своих собственных входных данных.

JavaScript
function NoRefsForm() {
const handleSubmit = e => {
e.preventDefault();
const form = e.target;
console.log(’email’, form.email, form.elements.email);
console.log(‘name’, form.name, form.elements.name);
}

return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor=»email»>Email address</label>
<input
id=»email»
name=»email»
/>
</div>
<div>
<label htmlFor=»name»>Full Name</label>
<input
id=»name»
name=»name»
/>
</div>
<button type=»submit»>Submit</button>
</form>
);
}

12345678910111213141516171819202122232425262728 function NoRefsForm() {  const handleSubmit = e => {    e.preventDefault();    const form = e.target;    console.log(’email’, form.email, form.elements.email);    console.log(‘name’, form.name, form.elements.name);  }   return (    <form onSubmit={handleSubmit}>      <div>        <label htmlFor=»email»>Email address</label>        <input          id=»email»          name=»email»        />      </div>      <div>        <label htmlFor=»name»>Full Name</label>        <input          id=»name»          name=»name»        />      </div>      <button type=»submit»>Submit</button>    </form>  );}

Input — это свойства самой формы, названные по их id и name. Они также доступны по адресу form.elements:

JavaScript
function App() {
const handleSubmit = (e) => {
e.preventDefault();
const form = e.target;
console.log(
form.email,
form.elements.email,
form.userEmail,
form.elements.userEmail);
};

return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor=»userEmail»>Email address</label>
<input id=»userEmail» name=»email» />
</div>
<button type=»submit»>Submit</button>
</form>
);
}

123456789101112131415161718192021 function App() {  const handleSubmit = (e) => {    e.preventDefault();    const form = e.target;    console.log(      form.email,      form.elements.email,      form.userEmail,      form.elements.userEmail);  };   return (    <form onSubmit={handleSubmit}>      <div>        <label htmlFor=»userEmail»>Email address</label>        <input id=»userEmail» name=»email» />      </div>      <button type=»submit»>Submit</button>    </form>  );}

Это напечатает один и тот же ввод 4 раза:

<input id=»userEmail» name=»email»></input>
<input id=»userEmail» name=»email»></input>
<input id=»userEmail» name=»email»></input>
<input id=»userEmail» name=»email»></input>

1234 <input id=»userEmail» name=»email»></input><input id=»userEmail» name=»email»></input><input id=»userEmail» name=»email»></input><input id=»userEmail» name=»email»></input>

Таким образом, мы можем исключить избыточное свойство name на входе, если оно нам больше не нужно. (нам нужно сохранить id, потому что htmlFor ссылается на него)

Массив form.elements полезен, если вам нужно перебрать каждый ввод, как если у вас есть куча динамически генерируемых вводов.

Доступные Label для форм

Каждый input должен иметь label. Input без label создает проблемы для программ чтения с экрана, что создает проблемы для людей… а текст-заполнитель, к сожалению, не помогает. Label можно делать двумя способами:

label рядом с input

Задайте для input id и label соответствующий htmlFor, и поместите элементы рядом. Порядок не имеет значения, пока идентификаторы совпадают.

<label htmlFor=»wat»>Email address</label>
<input id=»wat» name=»email» />

12 <label htmlFor=»wat»>Email address</label><input id=»wat» name=»email» />

input внутри label

Если вы поместите input в label, вам не нужны id и htmlFor. Однако вам понадобится способ ссылаться на ввод, поэтому укажите ему id или name.

<label>
Email Address
<input type=»email» name=»email» />
</label>

1234 <label>  Email Address  <input type=»email» name=»email» /></label>

Если вам нужно больше контроля над стилем текста, вы можете обернуть его в span.

Визуально скрыт, но все же доступен

При необходимости вы можете скрыть label с помощью CSS. Большинство крупных CSS-фреймворков имеют класс только для чтения с экрана, который часто sr-only, скрывает label таким образом, чтобы программы чтения с экрана могли ее прочитать. Вот общая реализация sr-only.

Что хорошо в label, так это то, что после того, как вы правильно их связали, браузер будет переводить клики по ярлыку как клики по полю ввода. Это наиболее заметно с переключателями — когда label установлена правильно, клик по тексту выберет нужный элемент, но в противном случае он вас проигнорирует.

Уменьшить форму Boilerplate с небольшими компонентами

Итак, вы добавили свои label, но вывод становятся длиннее и повторяется…

<div>
<label htmlFor=»email»>Email Address</label>
<input name=»email» id=»email»>
</div>

1234 <div>  <label htmlFor=»email»>Email Address</label>  <input name=»email» id=»email»></div>

Однако вы можете легко переместить это в компонент!

JavaScript
function Input({ name, label }) {
return (
<div>
<label htmlFor={name}>{label}</label>
<input name={name} id={name}>
</div>
);
}

12345678 function Input({ name, label }) {  return (    <div>      <label htmlFor={name}>{label}</label>      <input name={name} id={name}>    </div>  );}

Теперь каждый ввод снова прост.

<input name=»email» label=»Email Address»/>

1 <input name=»email» label=»Email Address»/>

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

Лучшая практика — использовать контролируемые входы?

На момент написания этой статьи в документации React есть рекомендации по входным данным:

Далее они говорят, что простым выходом является использование неконтролируемого ввода:

В документации нет точного объяснения аргументов, но я предполагаю, что их рекомендация проистекает из того факта, что контролируемые входные данные тесно связаны с подходом управляемого состояния, что является единственной причиной существования React. Неконтролируемые вводы затем рассматриваются как «аварийный выход», когда подход управляемого состояния не работает по какой-либо причине.

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

Если неконтролируемый ввод работает в вашем случае, используйте его! Он проще и быстрее. Не думаю, что я одинок в этом. Популярная библиотека response-hook-form использует неконтролируемые вводы под капотом, чтобы ускорить работу. И я видел, как некоторые идейные лидеры React спрашивали, почему мы не используем чаще неконтролируемые вводы. Может, пора задуматься!

Являются ли неконтролируемые вводы антипаттерном?

Неконтролируемые вводы — это такая же функция, как и любая другая, и они имеют некоторые компромиссы (о которых мы говорили выше), но они не являются антипаттерном. В React есть такие антипаттерны, как:

изменяющееся состояние вместо использования неизменяемости

дублирование значений из реквизита в состояние и попытка их синхронизации

выполнение побочных эффектов в теле функции компонента, а не в хуке useEffect

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

Неконтролируемые вводы сегодня немного необычны, но их использование не означает «сделать что-то неправильно». Это вопрос выбора правильного инструмента для работы. Если вы понимаете их ограничения и свой вариант использования, то можете быть вполне уверены в своем выборе.

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

Автор: Dave Ceddia

Источник: webformyself.com

Похожие статьи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Яндекс.Метрика
Открыть чат
Если есть вопросы пишите нам
Здравствуйте.
Чем вам помочь?