<input>¶
Встроенный компонент браузера <input>
позволяет отображать различные виды вводимых форм.
1 |
|
Описание¶
<input>
¶
Чтобы отобразить ввод, отобразите компонент встроенный в браузер <input>
.
1 |
|
Свойства
input
поддерживает все общие пропсы элементов.
Вы можете сделать input
управляемым, передав один из этих пропсов:
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
: Строка. Указываетid
формы, к которой принадлежит этот input. Если опущено, то это ближайшая родительская форма.formAction
: Строка. Переопределяет родительское<form action>
дляtype="submit"
иtype="image"
.formEnctype
: Строка. Переопределяет родительский<form enctype>
дляtype="submit"
иtype="image"
.formMethod
: Строка. Переопределяет родительский<метод формы>
дляtype="submit"
иtype="image"
.formNoValidate
: Строка. Переопределяет родительскую<form noValidate>
дляtype="submit"
иtype="image"
.formTarget
: Строка. Переопределяет родительскую<form target>
дляtype="submit"
иtype="image"
.height
: Строка. Определяет высоту изображения дляtype="image"
.list
: Строка. Указываетid
<datalist>
с опциями автозаполнения.max
: Число. Определяет максимальное значение числовых данных и данных времени.maxLength
: Число. Определяет максимальную длину текстовых и других вводов.
Предостережения
- Для флажков нужно
checked
(илиdefaultChecked
), а неvalue
(илиdefaultValue
). - Если текстовый ввод получает строковое значение
value
, он будет рассматриваться как управляемый. - Если чекбокс или радиокнопка получает булево свойство
checked
, они будут рассматриваться как управляемые. - Вход не может быть одновременно управляемым и неуправляемым.
- Вход не может переключаться между управляемым и неуправляемым в течение своего существования.
- Каждый управляемый вход нуждается в обработчике события
onChange
, который синхронно обновляет его базовое значение.
Использование¶
Отображение входов различных типов¶
Чтобы отобразить ввод, создайте компонент input
. По умолчанию это будет текстовый ввод. Вы можете передать type="checkbox"
для флажка, type="radio"
для радиокнопки, или один из других типов ввода.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
Предоставление метки для ввода¶
Обычно вы помещаете каждый input
в тег label
. Это сообщает браузеру, что данная метка связана с этим входом. Когда пользователь нажимает на метку, браузер автоматически фокусируется на вводе. Это также необходимо для обеспечения доступности: программа чтения с экрана объявит надпись на ярлыке, когда пользователь сфокусируется на связанном вводе.
Если вы не можете вложить input
в label
, свяжите их, передав одинаковый ID в <input id>
и <label htmlFor>
. Чтобы избежать конфликтов между несколькими экземплярами одного компонента, создайте такой ID с помощью useId
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Предоставление начального значения для ввода¶
Вы можете опционально указать начальное значение для любого входа. Для текстовых входов передавайте его как строку defaultValue
. Для флажков и радиокнопок начальное значение должно задаваться булевым значением defaultChecked
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
|
Чтение значений ввода при отправке формы¶
Добавьте <form>
вокруг ваших входных данных с <button type="submit">
внутри. Это вызовет обработчик события <form onSubmit>
. По умолчанию браузер отправит данные формы на текущий URL и обновит страницу. Вы можете отменить это поведение, вызвав e.preventDefault()
. Считайте данные формы с помощью new FormData(e.target)
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
|
Дайте name
каждому <input>
Дайте name
каждому <input>
, например <input name="firstName" defaultValue="Taylor" />
. Указанное вами name
будет использоваться в качестве ключа в данных формы, например { firstName: "Taylor" }
.
Тип <button>
По умолчанию любая <button>
внутри <form>
отправит ее. Это может быть неожиданно! Если у вас есть собственный пользовательский компонент React Button
, подумайте о возврате <button type="button">
вместо <button>
. Затем, чтобы быть однозначным, используйте <button type="submit">
для кнопок, которые должны отправлять форму.
Управление input с помощью переменной состояния¶
Input типа <input />
является неуправляемым. Даже если вы передаете начальное значение, например <input defaultValue="Initial text" />
, ваш JSX определяет только начальное значение. Он не контролирует, каким должно быть значение в данный момент.
Чтобы отобразить управляемый вход, передайте ему свойство value
(или checked
для чекбоксов и радио). React заставит вход всегда иметь переданное вами value
. Обычно для этого объявляется переменная состояния:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Контролируемый ввод имеет смысл, если вам все равно нужно состояние - например, для повторного отображения пользовательского интерфейса при каждом редактировании:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
Это также полезно, если вы хотите предложить несколько способов изменения состояния ввода (например, нажатием кнопки):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Значение value
, которое вы передаете управляемым компонентам, не должно быть undefined
или null
. Если вам нужно, чтобы начальное значение было пустым (как в случае с полем firstName
ниже), инициализируйте переменную состояния пустой строкой (''
).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
Если вы передадите value
без onChange
, то ввод будет невозможен
Когда вы управляете вводом, передавая ему некоторое value
, вы принуждаете его всегда иметь то значение, которое вы передали. Поэтому если вы передадите переменную состояния в качестве value
, но забудете синхронно обновить эту переменную состояния в обработчике события onChange
, React будет возвращать ввод после каждого нажатия клавиши к указанному вами value
.
Оптимизация повторного рендеринга при каждом нажатии клавиши¶
Когда вы используете управляемый ввод, вы устанавливаете состояние при каждом нажатии клавиши. Если компонент, содержащий ваше состояние, перерисовывает большое дерево, это может стать медленным. Есть несколько способов оптимизировать производительность повторного рендеринга.
Например, предположим, вы начинаете с формы, которая при каждом нажатии клавиши перерисовывает все содержимое страницы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Поскольку <PageContent />
не зависит от состояния ввода, вы можете перенести состояние ввода в свой собственный компонент:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Это значительно повышает производительность, поскольку теперь только SignupForm
рендерится при каждом нажатии клавиши.
Если нет возможности избежать повторного рендеринга (например, если PageContent
зависит от значения поискового ввода), useDeferredValue
позволяет сохранить отзывчивость управляемого ввода даже в середине большого повторного рендеринга.
Устранение неполадок¶
Мой текстовый ввод не обновляется, когда я ввожу текст¶
Если вы отображаете ввод с value
, но без onChange
, вы увидите ошибку в консоли:
1 2 |
|
Ошибка
Вы предоставили свойство value
полю формы без обработчика onChange
. Это приведет к тому, что поле будет доступно только для чтения. Если поле должно быть изменяемым, используйте defaultValue
. В противном случае установите либо onChange
, либо readOnly
.
Как следует из сообщения об ошибке, если вы хотите указать только начальное значение, передайте defaultValue
вместо этого:
1 2 |
|
Если вы хотите управлять этим входом с помощью переменной состояния, укажите обработчик onChange
:
1 2 3 4 5 |
|
Если значение намеренно предназначено только для чтения, добавьте параметр readOnly
, чтобы подавить ошибку:
1 2 |
|
Мой флажок не обновляется, когда я нажимаю на него¶
Если вы отобразите флажок с checked
, но без onChange
, вы увидите ошибку в консоли:
1 2 |
|
Ошибка
Вы предоставили свойство checked
полю формы без обработчика onChange
. Это приведет к тому, что поле будет доступно только для чтения. Если поле должно быть изменяемым, используйте defaultChecked
. В противном случае установите либо onChange
, либо readOnly
.
Как следует из сообщения об ошибке, если вы хотите только указать начальное значение, передайте defaultChecked
вместо этого:
1 2 |
|
Если вы хотите управлять этим флажком с помощью переменной состояния, укажите обработчик onChange
:
1 2 3 4 5 6 |
|
Для флажков нужно читать e.target.checked
, а не e.target.value
.
Если флажок намеренно предназначен только для чтения, добавьте параметр readOnly
, чтобы подавить ошибку:
1 2 3 4 5 6 |
|
Мой каретка ввода перескакивает в начало при каждом нажатии клавиши¶
Если вы управляете вводом, вы должны обновить его переменную состояния до значения ввода из DOM во время onChange
.
Вы не можете обновить ее до значения, отличного от e.target.value
(или e.target.checked
для флажков):
1 2 3 4 |
|
Вы также не можете обновлять его асинхронно:
1 2 3 4 5 6 |
|
Чтобы исправить свой код, обновите его синхронно с e.target.value
:
1 2 3 4 |
|
Если это не устраняет проблему, возможно, что ввод удаляется и добавляется из DOM при каждом нажатии клавиши. Это может произойти, если вы случайно сбрасываете состояние при каждом повторном рендере, например, если input
или один из его родителей всегда получает другой атрибут key
, или если вы вложены определения функций компонентов (что не поддерживается и приводит к тому, что "внутренний" компонент всегда считается другим деревом).
Я получаю ошибку: "Компонент изменяет неконтролируемый вход на контролируемый"¶
Если вы передаете компоненту value
, оно должно оставаться строкой в течение всего времени его работы.
Вы не можете сначала передать value={undefined}
, а затем передать value="some string"
, потому что React не будет знать, хотите ли вы, чтобы компонент был неуправляемым или управляемым. Управляемый компонент всегда должен получать строковое value
, а не null
или undefined
.
Если ваше value
приходит из API или переменной состояния, оно может быть инициализировано в null
или undefined
. В этом случае либо изначально установите его в пустую строку (''
), либо передайте value={someValue ?? ''}
, чтобы убедиться, что value
является строкой.
Аналогично, если вы передаете checked
флажку, убедитесь, что это всегда булево значение.
Источник — https://react.dev/reference/react-dom/components/input