Spec-Zone.ru › React 18

<input>

Встроенный в браузер <input> компонент позволяет отображать различные типы входных элементов формы.

<input />
  • Ссылка
    • <input>
  • Использование
    • Отображение входных элементов различных типов
    • Добавление метки для входного элемента
    • Установление начального значения для входного элемента
    • Чтение значений входных элементов при отправке формы
    • Управление входным элементом с помощью переменной состояния
    • Оптимизация повторного рендеринга при каждом нажатии клавиши
  • Отладка
    • Ввод текста не обновляется при вводе
    • Флажок не обновляется при нажатии
    • Курсор ввода перескакивает в начало при каждом нажатии клавиши
    • Ошибка: «Компонент изменяет неконтролируемый входной элемент на контролируемый»

Ссылка

<input>

Для отображения входного элемента используйте встроенный в браузер <input> компонент.

<input name="myInput" />

См. дополнительные примеры ниже.

Свойства

<input> поддерживает все общие свойства элемента.

Кандидатская версия

Расширения React для свойства formAction в настоящее время доступны только в каналах React Canary и экспериментальных каналах. В стабильных выпусках React formAction работает только как встроенный HTML-компонент браузера. Подробнее о каналах выпуска React.

formAction: Строка или функция. Переопределяет родительское <form action> для type="submit" и type="image". При передаче URL в action форма будет вести себя как стандартная HTML-форма. При передаче функции в formAction функция обработает отправку формы. См. <form action>.

Вы можете сделать входной элемент управляемым, передав одно из этих свойств:

  • checked: Булево значение. Для входного элемента типа флажок или радиокнопка управляет, выбран ли он.
  • value: Строка. Для текстового поля управляет его текстом. (Для радиокнопки указывает данные формы).

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

Эти <input> свойства актуальны только для неконтролируемых входных элементов:

  • defaultChecked: Булево значение. Указывает начальное значение для type="checkbox" и type="radio" входных элементов.
  • defaultValue: Строка. Указывает начальное значение для текстового поля.

Эти <input> свойства актуальны как для неконтролируемых, так и для контролируемых входных элементов:

  • accept: Строка. Указывает типы файлов, которые принимает элемент ввода type="file".
  • alt: Строка. Указывает альтернативный текст изображения для элемента ввода type="image".
  • capture: Строка. Указывает медиаданные (микрофон, видео или камеру), которые будут захвачены элементом ввода type="file".
  • autoComplete: Строка. Указывает одно из возможных поведений автозаполнения автозаполнения.
  • autoFocus: Булево значение. Если true, React сфокусирует элемент при монтировании.
  • dirname: Строка. Указывает имя поля формы для определения направления элемента.
  • disabled: Булево значение. Если true, элемент ввода будет неактивным и отображаться в затемненном виде.
  • children: <input> не принимает дочерние элементы.
  • form: Строка. Указывает форму, к которой относится данный элемент ввода. Если опущено, используется ближайшая родительская форма.
  • formAction: Строка. Переопределяет родительское свойство <form action> для type="submit" и type="image".
  • formEnctype: Строка. Переопределяет родительское свойство <form enctype> для type="submit" и type="image".
  • formMethod: Строка. Переопределяет родительское свойство <form method> для type="submit" и type="image".
  • formNoValidate: Строка. Переопределяет родительское свойство <form noValidate> для type="submit" и type="image".
  • formTarget: Строка. Переопределяет родительское свойство <form target> для type="submit" и type="image".
  • height: Строка. Указывает высоту изображения для type="image".
  • list: Строка. Указывает список id с возможностями автозаполнения.
  • max: Число. Указывает максимальное значение для числовых и датно-временных элементов ввода.
  • maxLength: Число. Указывает максимальную длину текста и других элементов ввода.
  • min: Число. Указывает минимальное значение для числовых и датно-временных элементов ввода.
  • minLength: Число. Указывает минимальную длину текста и других элементов ввода.
  • multiple: Булево значение. Указывает, разрешено ли вводить несколько значений для <type="file" и type="email".
  • name: Строка. Указывает имя элемента ввода, которое передаётся совместно с формой.
  • onChange: Функция обработчика Event. Необходима для управляемых элементов ввода. Срабатывает немедленно при изменении значения пользователем (например, при каждом нажатии клавиши). Ведёт себя как браузерное событие input.
  • onChangeCapture: Версия onChange, срабатывающая на фазе захвата.
  • onInput: Функция обработчика Event. Срабатывает немедленно при изменении значения пользователем. По историческим причинам в React принято использовать onChange, которое работает аналогично.
  • onInputCapture: Версия onInput, срабатывающая на фазе захвата.
  • onInvalid: Функция обработчика Event. Срабатывает, если элемент ввода не проходит валидацию при отправке формы. В отличие от встроенного события invalid, событие React onInvalid распространяется.
  • onInvalidCapture: Версия onInvalid, срабатывающая на фазе захвата.
  • onSelect: Функция обработчика Event. Срабатывает после изменения выделения внутри элемента <input>. React расширяет событие onSelect таким образом, что оно также срабатывает для пустого выделения и при редактировании (что может повлиять на выделение).
  • onSelectCapture: Версия onSelect, срабатывающая на фазе захвата.
  • pattern: Строка. Указывает шаблон, которому должен соответствовать элемент value.
  • placeholder: Строка. Отображается в затемнённом цвете, когда значение элемента ввода пустое.
  • readOnly: Булево значение. Если true, пользователь не может редактировать элемент ввода.
  • required: Булево значение. Если true, для отправки формы необходимо указать значение.
  • size: Число. Аналогично установке ширины, но единицы измерения зависят от элемента управления.
  • src: Строка. Указывает источник изображения для элемента ввода type="image".
  • step: Положительное число или строка 'any'. Указывает расстояние между допустимыми значениями.
  • type: Строка. Один из типов элементов ввода.
  • width: Строка. Указывает ширину изображения для элемента ввода type="image".

Примечания

  • Для чекбоксов необходимы checked (или defaultChecked), а не value (или defaultValue).
  • Если текстовому элементу ввода передаётся строковый value параметр, он будет обрабатываться как управляемый.
  • Если чекбоксу или радиокнопке передаётся булевый checked параметр, он будет обрабатываться как управляемый.
  • Элемент ввода не может быть одновременно управляемым и неуправляемым.
  • Элемент ввода не может переключаться между управляемым и неуправляемым состоянием в процессе работы.
  • Каждый управляемый элемент ввода требует обработчика события onChange для синхронного обновления его базового значения.

Использование

Отображение элементов ввода различных типов

Для отображения поля ввода, используйте компонент <input>. По умолчанию это текстовое поле ввода. Вы можете передать type="checkbox" для создания флажка, type="radio" для радиокнопки, или один из других типов input.

export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input type="radio" name="myRadio" value="option2" />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}


Предоставление метки для поля ввода

Обычно каждое <input> помещается внутри тега <label>. Это сообщает браузеру, что эта метка связана с этим полем ввода. Когда пользователь нажимает на метку, браузер автоматически фокусирует поле ввода. Это также важно для доступности: средство чтения с экрана объявит текст метки, когда пользователь сфокусируется на связанном поле ввода.

Если вы не можете вложить <input> в <label>, свяжите их, передав один и тот же идентификатор в <input id> и <label htmlFor>. Чтобы избежать конфликтов между несколькими экземплярами одного компонента, сгенерируйте такой идентификатор с помощью useId.

import { useId } from 'react';

export default function Form() {
  const ageInputId = useId();
  return (
    <>
      <label>
        Your first name:
        <input name="firstName" />
      </label>
      <hr />
      <label htmlFor={ageInputId}>Your age:</label>
      <input id={ageInputId} name="age" type="number" />
    </>
  );
}


Указание начального значения для поля ввода

Вы можете указать начальное значение для любого поля ввода. Передайте его как строку defaultValue для текстовых полей ввода. Для флажков и радиокнопок начальное значение должно быть указано с помощью булевой переменной defaultChecked.

export default function MyForm() {
  return (
    <>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label>
          <input type="radio" name="myRadio" value="option1" />
          Option 1
        </label>
        <label>
          <input
            type="radio"
            name="myRadio"
            value="option2"
            defaultChecked={true} 
          />
          Option 2
        </label>
        <label>
          <input type="radio" name="myRadio" value="option3" />
          Option 3
        </label>
      </p>
    </>
  );
}


Чтение значений полей ввода при отправке формы

Окружите ваши поля ввода тегом <form> с тегом <button type="submit"> внутри. Это вызовет ваш обработчик события <form onSubmit>. По умолчанию браузер отправит данные формы на текущий URL и обновит страницу. Вы можете изменить это поведение, вызвав e.preventDefault(). Прочтите данные формы с помощью new FormData(e.target).

export default function MyForm() {
  function handleSubmit(e) {
    // Prevent the browser from reloading the page
    e.preventDefault();

    // Read the form data
    const form = e.target;
    const formData = new FormData(form);

    // You can pass formData as a fetch body directly:
    fetch('/some-api', { method: form.method, body: formData });

    // Or you can work with it as a plain object:
    const formJson = Object.fromEntries(formData.entries());
    console.log(formJson);
  }

  return (
    <form method="post" onSubmit={handleSubmit}>
      <label>
        Text input: <input name="myInput" defaultValue="Some initial value" />
      </label>
      <hr />
      <label>
        Checkbox: <input type="checkbox" name="myCheckbox" defaultChecked={true} />
      </label>
      <hr />
      <p>
        Radio buttons:
        <label><input type="radio" name="myRadio" value="option1" /> Option 1</label>
        <label><input type="radio" name="myRadio" value="option2" defaultChecked={true} /> Option 2</label>
        <label><input type="radio" name="myRadio" value="option3" /> Option 3</label>
      </p>
      <hr />
      <button type="reset">Reset form</button>
      <button type="submit">Submit form</button>
    </form>
  );
}

Примечание

Присвойте name каждому <input>, например, <input name="firstName" defaultValue="Taylor" />. name что вы указали, будет использоваться в качестве ключа в данных формы, например, { firstName: "Taylor" }.

Возможная ошибка

По умолчанию любое <button> внутри <form> будет отправлять форму. Это может быть неожиданно! Если у вас есть собственный пользовательский компонент React Button, рассмотрите возможность возврата <button type="button"> вместо <button>. Затем, чтобы быть ясным, используйте <button type="submit"> для кнопок, которые должны отправлять форму.


Управление полем ввода с помощью переменной состояния

Поле ввода, подобное <input />, является неуправляемым. Даже если вы передаете начальное значение, как <input defaultValue="Initial text" />, ваш JSX только определяет начальное значение. Он не управляет текущим значением.

Для отрисовки управляемого поля ввода передайте свойство value (или checked для флажков и радиокнопок). React заставит поле ввода всегда иметь значение value, которое вы передали. Обычно это делается объявлением переменной состояния:

function Form() {
  const [firstName, setFirstName] = useState(''); // Declare a state variable...
  // ...
  return (
    <input
      value={firstName} // ...force the input's value to match the state variable...
      onChange={e => setFirstName(e.target.value)} // ... and update the state variable on any edits!
    />
  );
}

Управляемое поле ввода имеет смысл, если вам все равно нужна переменная состояния — например, для повторной отрисовки вашего пользовательского интерфейса при каждом изменении:

function Form() {
  const [firstName, setFirstName] = useState('');
  return (
    <>
      <label>
        First name:
        <input value={firstName} onChange={e => setFirstName(e.target.value)} />
      </label>
      {firstName !== '' && <p>Your name is {firstName}.</p>}
      ...

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

function Form() {
  // ...
  const [age, setAge] = useState('');
  const ageAsNumber = Number(age);
  return (
    <>
      <label>
        Age:
        <input
          value={age}
          onChange={e => setAge(e.target.value)}
          type="number"
        />
        <button onClick={() => setAge(ageAsNumber + 10)}>
          Add 10 years
        </button>

Значение value, которое вы передаёте управляемым компонентам, не должно быть undefined или null. Если вам нужно, чтобы начальное значение было пустым (например, с полем firstName ниже), инициализируйте вашу переменную состояния пустой строкой ('').

import { useState } from 'react';

export default function Form() {
  const [firstName, setFirstName] = useState('');
  const [age, setAge] = useState('20');
  const ageAsNumber = Number(age);
  return (
    <>
      <label>
        First name:
        <input
          value={firstName}
          onChange={e => setFirstName(e.target.value)}
        />
      </label>
      <label>
        Age:
        <input
          value={age}
          onChange={e => setAge(e.target.value)}
          type="number"
        />
        <button onClick={() => setAge(ageAsNumber + 10)}>
          Add 10 years
        </button>
      </label>
      {firstName !== '' &&
        <p>Your name is {firstName}.</p>
      }
      {ageAsNumber > 0 &&
        <p>Your age is {ageAsNumber}.</p>
      }
    </>
  );
}

Возможная ошибка

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


Оптимизация повторной отрисовки при каждом нажатии клавиши

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

Например, предположим, что вы начинаете с формы, которая перерисовывает всё содержимое страницы при каждом нажатии клавиши:

function App() {
  const [firstName, setFirstName] = useState('');
  return (
    <>
      <form>
        <input value={firstName} onChange={e => setFirstName(e.target.value)} />
      </form>
      <PageContent />
    </>
  );
}

Поскольку <PageContent /> не зависит от состояния поля ввода, вы можете поместить состояние поля ввода в собственный компонент:

function App() {
  return (
    <>
      <SignupForm />
      <PageContent />
    </>
  );
}

function SignupForm() {
  const [firstName, setFirstName] = useState('');
  return (
    <form>
      <input value={firstName} onChange={e => setFirstName(e.target.value)} />
    </form>
  );
}

Это значительно улучшает производительность, так как теперь только SignupForm перерисовывается при каждом нажатии клавиши.

Если избежать повторной отрисовки невозможно (например, если PageContent зависит от значения поля поиска), useDeferredValue позволяет поддерживать отзывчивость управляемого поля ввода даже во время большой повторной отрисовки.


Отладка

Поле ввода текста не обновляется при вводе

Если вы отрисовываете поле ввода с value, но без onChange, вы увидите ошибку в консоли:

// 🔴 Bug: controlled text input with no onChange handler
<input value={something} />
Консоль
Вы передали свойство value полю формы без обработчика onChange. Это приведет к отображению только для чтения. Если поле должно быть изменяемым, используйте defaultValue. В противном случае установите либо onChange, либо readOnly.

Как показывает сообщение об ошибке, если вы хотели только указать начальное значение, передайте defaultValue вместо этого:

// ✅ Good: uncontrolled input with an initial value
<input defaultValue={something} />

Если вы хотите управлять этим полем ввода с помощью переменной состояния, укажите обработчик onChange:

// ✅ Good: controlled input with onChange
<input value={something} onChange={e => setSomething(e.target.value)} />

Если значение преднамеренно только для чтения, добавьте свойство readOnly для подавления ошибки:

// ✅ Good: readonly controlled input without on change
<input value={something} readOnly={true} />

Флажок не обновляется при нажатии на него

Если вы отрисовываете флажок с checked, но без onChange, вы увидите ошибку в консоли:

// 🔴 Bug: controlled checkbox with no onChange handler
<input type="checkbox" checked={something} />
Консоль
Вы передали свойство checked полю формы без обработчика onChange. Это приведет к отображению только для чтения. Если поле должно быть изменяемым, используйте defaultChecked. В противном случае установите либо onChange, либо readOnly.

Как показывает сообщение об ошибке, если вы хотели только указать начальное значение, передайте defaultChecked вместо этого:

// ✅ Good: uncontrolled checkbox with an initial value
<input type="checkbox" defaultChecked={something} />

Если вы хотите управлять этим флажком с помощью переменной состояния, укажите обработчик onChange:

// ✅ Good: controlled checkbox with onChange
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />

Возможная ошибка

Для флажков необходимо читать e.target.checked, а не e.target.value.

Если флажок преднамеренно только для чтения, добавьте свойство readOnly для подавления ошибки:

// ✅ Good: readonly controlled input without on change
<input type="checkbox" checked={something} readOnly={true} />

Курсор ввода перескакивает в начало при каждом нажатии клавиши

Если вы управляете полем ввода, вы должны обновить его переменную состояния до значения поля ввода из DOM во время onChange.

Вы не можете обновить её на что-то другое, кроме e.target.value (или e.target.checked для флажков):

function handleChange(e) {
  // 🔴 Bug: updating an input to something other than e.target.value
  setFirstName(e.target.value.toUpperCase());
}

Вы также не можете обновить её асинхронно:

function handleChange(e) {
  // 🔴 Bug: updating an input asynchronously
  setTimeout(() => {
    setFirstName(e.target.value);
  }, 100);
}

Чтобы исправить код, обновите его синхронно на e.target.value:

function handleChange(e) {
  // ✅ Updating a controlled input to e.target.value synchronously
  setFirstName(e.target.value);
}

Если это не решит проблему, возможно, поле ввода удаляется и добавляется заново из DOM при каждом нажатии клавиши. Это может произойти, если вы случайно сбрасываете состояние при каждом перерисовке, например, если у поля ввода или одного из его родительских элементов всегда есть другое атрибут key, или если вы вкладываете определения функций компонентов (что не поддерживается и приводит к тому, что «внутренний» компонент всегда считается другим деревом).


Ошибка: «Компонент изменяет неуправляемый элемент ввода на управляемый»

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

Вы не можете передать value={undefined} сначала, а затем передать value="some string", потому что React не будет знать, хотите ли вы, чтобы компонент был неуправляемым или управляемым. Управляемый компонент должен всегда получать строку value, а не null или undefined.

Если ваше value поступает из API или переменной состояния, оно может быть инициализировано значением null или undefined. В этом случае либо установите его в пустую строку ('') изначально, либо передайте value={someValue ?? ''}, чтобы убедиться, что value является строкой.

Аналогично, если вы передаёте checked флажку, убедитесь, что это всегда булево значение.

© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://18.react.dev/reference/react-dom/components/input

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API