<textarea>
Встроенный браузерный компонент <textarea> позволяет отображать многострочный текстовый ввод.
<textarea />
Справочник
<textarea>
Для отображения текстовой области используйте встроенный браузерный компонент <textarea>.
<textarea name="postContent" /> Свойства
<textarea> поддерживает все общие свойства элементов.
Вы можете сделать текстовую область контролируемой, передав свойство value:
-
value: Строка. Управляет текстом внутри текстовой области.
Когда вы передаёте value, вы также должны передать обработчик onChange, который обновляет переданное значение.
Если ваша <textarea> не контролируется, вы можете передать свойство defaultValue вместо него:
-
defaultValue: Строка. Указывает начальное значение для текстовой области.
Эти <textarea> свойства актуальны как для неконтролируемых, так и для контролируемых текстовых областей:
-
autoComplete:'on'или'off'. Указывает поведение автозаполнения. -
autoFocus: Логическое значение. Еслиtrue, React сфокусирует элемент при монтировании. -
children:<textarea>не принимает дочерние элементы. Чтобы установить начальное значение, используйтеdefaultValue. -
cols: Число. Указывает ширину по умолчанию в средних ширинах символов. По умолчанию20. -
disabled: Логическое значение. Еслиtrue, ввод будет неактивным и будет выглядеть затемнённым. -
form: Строка. Указываетidформы, к которой относится этот ввод. Если опущено, используется ближайшая родительская форма. -
maxLength: Число. Указывает максимальную длину текста. -
minLength: Число. Указывает минимальную длину текста. -
name: Строка. Указывает имя для этого ввода, которое передаётся с формой. -
onChange: Функция-обработчикEvent. Необходима для контролируемых текстовых областей. Вызывается сразу после изменения значения пользователем (например, при каждом нажатии клавиши). Ведёт себя как событие браузераinput. -
onChangeCapture: ВерсияonChange, которая срабатывает на стадии захвата. -
onInput: Функция-обработчикEvent. Вызывается сразу после изменения значения пользователем. По историческим причинам в React принято использоватьonChange, которое работает аналогично. -
onInputCapture: ВерсияonInput, которая срабатывает на стадии захвата. -
onInvalid: Функция-обработчикEvent. Вызывается, если ввод не проходит валидацию при отправке формы. В отличие от встроенного событияinvalid, событие ReactonInvalidраспространяется. -
onInvalidCapture: ВерсияonInvalid, которая срабатывает на стадии захвата. -
onSelect: Функция-обработчикEvent. Вызывается после изменения выделения внутри<textarea>. React расширяет событиеonSelect, чтобы оно также срабатывало при пустом выделении и при редактировании (что может повлиять на выделение). -
onSelectCapture: ВерсияonSelect, которая срабатывает на стадии захвата. -
placeholder: Строка. Отображается в затемнённом цвете, когда значение текстовой области пустое. -
readOnly: Логическое значение. Еслиtrue, текстовая область недоступна для редактирования пользователем. -
required: Логическое значение. Еслиtrue, значение должно быть предоставлено для отправки формы. -
rows: Число. Указывает высоту по умолчанию в средних высотах символов. По умолчанию2. -
wrap:'hard','soft', или'off'. Указывает, как текст должен быть переведён при отправке формы.
Ограничения
- Передача дочерних элементов, таких как
<textarea>something</textarea>, запрещена. ИспользуйтеdefaultValueдля начального содержимого. - Если текстовая область получает строковое свойство
value, оно будет обработано как контролируемое. - Текстовая область не может быть одновременно контролируемой и неконтролируемой.
- Текстовая область не может переключаться между контролируемым и неконтролируемым состоянием в течение своего жизненного цикла.
- Каждая контролируемая текстовая область требует обработчика события
onChangeдля синхронного обновления своего базового значения.
Использование
Отображение текстовой области
Отобразите <textarea>, чтобы отобразить текстовую область. Вы можете указать её размер по умолчанию с помощью атрибутов rows и cols, но по умолчанию пользователь сможет её переразмерять. Для отключения переразмещения можно указать resize: none в CSS.
export default function NewPost() { return ( <label> Write your post: <textarea name="postContent" rows={4} cols={40} /> </label> ); }
Добавление метки к текстовой области
Обычно, вы помещаете каждую <textarea> внутри тега <label>. Это сообщает браузеру, что эта метка связана с этой текстовой областью. При нажатии пользователем на метку браузер сфокусируется на текстовой области. Это также важно для доступности: средство чтения с экрана прочитает текст метки, когда пользователь сфокусируется на текстовой области.
Если вы не можете вложить <textarea> в <label>, свяжите их, передав один и тот же идентификатор в <textarea id> и <label htmlFor>. Чтобы избежать конфликтов между экземплярами одного компонента, генерируйте такой идентификатор с помощью useId.
import { useId } from 'react'; export default function Form() { const postTextAreaId = useId(); return ( <> <label htmlFor={postTextAreaId}> Write your post: </label> <textarea id={postTextAreaId} name="postContent" rows={4} cols={40} /> </> ); }
Установка начального значения текстовой области
Вы можете необязательно указать начальное значение для текстовой области. Передайте его как строку defaultValue.
export default function EditPost() { return ( <label> Edit your post: <textarea name="postContent" defaultValue="I really enjoyed biking yesterday!" rows={4} cols={40} /> </label> ); }
Опасность
В отличие от HTML, передача начального текста, как <textarea>Some content</textarea>, не поддерживается.
Чтение значения текстовой области при отправке формы
Добавьте <form> вокруг вашей области ввода текста с <button type="submit"> внутри. Это вызовет ваш обработчик события <form onSubmit>. По умолчанию браузер отправит данные формы на текущий URL и обновит страницу. Вы можете изменить это поведение, вызвав e.preventDefault(). Прочтите данные формы с помощью new FormData(e.target).
export default function EditPost() { 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> Post title: <input name="postTitle" defaultValue="Biking" /> </label> <label> Edit your post: <textarea name="postContent" defaultValue="I really enjoyed biking yesterday!" rows={4} cols={40} /> </label> <hr /> <button type="reset">Reset edits</button> <button type="submit">Save post</button> </form> ); }
Примечание
Укажите name для вашего <textarea>, например <textarea name="postContent" />. name значение, которое вы указали, будет использоваться в качестве ключа в данных формы, например { postContent: "Your post" }.
Опасная ситуация
По умолчанию, любой <button> внутри <form> будет отправлять его. Это может быть неожиданно! Если у вас есть свой собственный пользовательский компонент Button React, рассмотрите возможность возврата <button type="button"> вместо <button>. Затем, чтобы быть ясными, используйте <button type="submit"> для кнопок, которые должны отправить форму.
Управление областью ввода текста с помощью переменной состояния
Область ввода текста, как <textarea />, неуправляемая. Даже если вы передадите начальное значение, как <textarea defaultValue="Initial text" />, ваш JSX только определяет начальное значение, а не текущее.
Для рендеринга управляемой области ввода текста передайте свойство value в неё. React заставит область ввода текста всегда иметь значение value, которое вы передали. Обычно вы управляете областью ввода текста, объявив переменную состояния:
function NewPost() {
const [postContent, setPostContent] = useState(''); // Declare a state variable...
// ...
return (
<textarea
value={postContent} // ...force the input's value to match the state variable...
onChange={e => setPostContent(e.target.value)} // ... and update the state variable on any edits!
/>
);
} Это полезно, если вы хотите повторно отобразить часть пользовательского интерфейса в ответ на каждый ввод с клавиатуры.
{ "dependencies": { "react": "latest", "react-dom": "latest", "react-scripts": "latest", "remarkable": "2.0.1" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test --env=jsdom", "eject": "react-scripts eject" }, "devDependencies": {} }
Опасная ситуация
Если вы передадите value без onChange, ввести в область ввода текста будет невозможно. Когда вы управляете областью ввода текста, передавая ей некоторое значение value, вы принудительно устанавливаете её значение на то, которое вы передали. Таким образом, если вы передадите переменную состояния в качестве value, но забудете обновить эту переменную состояния синхронно во время обработчика события onChange, React вернёт область ввода текста после каждого ввода с клавиатуры к значению value, которое вы указали.
Отладка
Моя область ввода текста не обновляется при вводе
Если вы отображаете область ввода текста с value, но без onChange, вы увидите ошибку в консоли:
// 🔴 Bug: controlled text area with no onChange handler
<textarea value={something} />
value полю формы без обработчика onChange. Это отобразит поле только для чтения. Если поле должно быть изменяемым, используйте defaultValue. В противном случае установите либо onChange, либо readOnly. Как показывает сообщение об ошибке, если вы хотели только указать начальное значение, передайте defaultValue вместо этого:
// ✅ Good: uncontrolled text area with an initial value
<textarea defaultValue={something} /> Если вы хотите управлять этой областью ввода текста с помощью переменной состояния, укажите обработчик onChange:
// ✅ Good: controlled text area with onChange
<textarea value={something} onChange={e => setSomething(e.target.value)} /> Если значение преднамеренно только для чтения, добавьте свойство readOnly, чтобы подавить ошибку:
// ✅ Good: readonly controlled text area without on change
<textarea value={something} readOnly={true} /> Курсор моей области ввода текста перескакивает в начало при каждом нажатии клавиши
Если вы управляете областью ввода текста, вы должны обновить её переменную состояния значением из DOM во время onChange.
Вы не можете обновить её на что-то кроме e.target.value:
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, или если вы вкладываете определения компонентов (что запрещено в React и приводит к повторной установке «внутреннего» компонента при каждом рендеринге).
Я получаю ошибку: «Компонент изменяет неуправляемый ввод на управляемый»
Если вы предоставляете свойство value компоненту, оно должно оставаться строкой на протяжении всего своего жизненного цикла.
Вы не можете сначала передать value={undefined}, а затем передать value="some string", потому что React не будет знать, хотите ли вы, чтобы компонент был неуправляемым или управляемым. Управляемый компонент всегда должен получать строку value, а не null или undefined.
Если ваше value поступает из API или переменной состояния, оно может быть инициализировано null или undefined. В этом случае либо установите его в пустую строку ('') изначально, либо передайте value={someValue ?? ''}, чтобы гарантировать, что value является строкой.
© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://18.react.dev/reference/react-dom/components/textarea