内置浏览器 <textarea> 组件 允许你渲染多行文本输入。

¥The built-in browser <textarea> component lets you render a multiline text input.

<textarea />

参考

¥Reference

<textarea>

要显示文本区域,请渲染 内置浏览器 <textarea> 组件。

¥To display a text area, render the built-in browser <textarea> component.

<textarea name="postContent" />

请参阅下面的更多示例。

¥See more examples below.

属性

¥Props

<textarea> 支持所有 普通元素属性。

¥<textarea> supports all common element props.

你可以通过传递 value 属性来 控制文本区域

¥You can make a text area controlled by passing a value prop:

  • value:一个字符串。控制文本区域内的文本。

    ¥value: A string. Controls the text inside the text area.

当你传递 value 时,你还必须传递一个更新传递值的 onChange 处理程序。

¥When you pass value, you must also pass an onChange handler that updates the passed value.

如果你的 <textarea> 不受控制,你可以传递 defaultValue 属性:

¥If your <textarea> is uncontrolled, you may pass the defaultValue prop instead:

  • defaultValue:一个字符串。为文本区域指定 初始值

    ¥defaultValue: A string. Specifies the initial value for a text area.

这些 <textarea> 属性与不受控和受控文本区域相关:

¥These <textarea> props are relevant both for uncontrolled and controlled text areas:

  • autoComplete'on''off'。指定自动补齐行为。

    ¥autoComplete: Either 'on' or 'off'. Specifies the autocomplete behavior.

  • autoFocus:一个布尔值。如果是 true,React 会将元素集中在挂载上。

    ¥autoFocus: A boolean. If true, React will focus the element on mount.

  • children<textarea> 不接受子级。要设置初始值,请使用 defaultValue

    ¥children: <textarea> does not accept children. To set the initial value, use defaultValue.

  • cols:一个号码。指定平均字符宽度的默认宽度。默认为 20

    ¥cols: A number. Specifies the default width in average character widths. Defaults to 20.

  • disabled:一个布尔值。如果是 true,输入将不会是交互式的,并且会显示为灰色。

    ¥disabled: A boolean. If true, the input will not be interactive and will appear dimmed.

  • form:一个字符串。指定此输入所属的 <form>id。如果省略,它是最接近的父表单。

    ¥form: A string. Specifies the id of the <form> this input belongs to. If omitted, it’s the closest parent form.

  • maxLength:一个号码。指定文本的最大长度。

    ¥maxLength: A number. Specifies the maximum length of text.

  • minLength:一个号码。指定文本的最小长度。

    ¥minLength: A number. Specifies the minimum length of text.

  • name:一个字符串。指定此输入的名称 与表格一起提交。

    ¥name: A string. Specifies the name for this input that’s submitted with the form.

  • onChange:一个 Event 处理程序 函数。控制文本区域。 需要 当输入的值被用户更改时立即触发(例如,它在每次击键时触发)。行为类似于浏览器 input 事件。

    ¥onChange: An Event handler function. Required for controlled text areas. Fires immediately when the input’s value is changed by the user (for example, it fires on every keystroke). Behaves like the browser input event.

  • onChangeCapture:在 捕获阶段。 中触发的 onChange 版本

    ¥onChangeCapture: A version of onChange that fires in the capture phase.

  • onInput:一个 Event 处理程序 函数。当用户更改值时立即触发。由于历史原因,在 React 中惯用的是使用 onChange,它的工作方式类似。

    ¥onInput: An Event handler function. Fires immediately when the value is changed by the user. For historical reasons, in React it is idiomatic to use onChange instead which works similarly.

  • onInputCapture:在 捕获阶段。 中触发的 onInput 版本

    ¥onInputCapture: A version of onInput that fires in the capture phase.

  • onInvalid:一个 Event 处理程序 函数。如果输入在表单提交时验证失败,则触发。与内置的 invalid 事件不同,React onInvalid 事件冒泡。

    ¥onInvalid: An Event handler function. Fires if an input fails validation on form submit. Unlike the built-in invalid event, the React onInvalid event bubbles.

  • onInvalidCapture:在 捕获阶段。 中触发的 onInvalid 版本

    ¥onInvalidCapture: A version of onInvalid that fires in the capture phase.

  • onSelect:一个 Event 处理程序 函数。在 <textarea> 内的选择更改后触发。React 扩展了 onSelect 事件以在空选择和编辑时触发(这可能会影响选择)。

    ¥onSelect: An Event handler function. Fires after the selection inside the <textarea> changes. React extends the onSelect event to also fire for empty selection and on edits (which may affect the selection).

  • onSelectCapture:在 捕获阶段。 中触发的 onSelect 版本

    ¥onSelectCapture: A version of onSelect that fires in the capture phase.

  • placeholder:一个字符串。当文本区域值为空时,以暗淡的颜色显示。

    ¥placeholder: A string. Displayed in a dimmed color when the text area value is empty.

  • readOnly:一个布尔值。如果为 true,则文本区域不可由用户编辑。

    ¥readOnly: A boolean. If true, the text area is not editable by the user.

  • required:一个布尔值。如果是 true,则必须提供该值以便提交表单。

    ¥required: A boolean. If true, the value must be provided for the form to submit.

  • rows:一个号码。以平均字符高度指定默认高度。默认为 2

    ¥rows: A number. Specifies the default height in average character heights. Defaults to 2.

  • wrap'hard''soft''off'。指定提交表单时应如何换行文本。

    ¥wrap: Either 'hard', 'soft', or 'off'. Specifies how the text should be wrapped when submitting a form.

注意事项

¥Caveats

  • 不允许像 <textarea>something</textarea> 这样的子级通过。使用 defaultValue 作为初始内容。

    ¥Passing children like <textarea>something</textarea> is not allowed. Use defaultValue for initial content.

  • 如果文本区域接收到字符串 value 属性,它将是 作为控制处理。

    ¥If a text area receives a string value prop, it will be treated as controlled.

  • 文本区域不能同时受控和不受控。

    ¥A text area can’t be both controlled and uncontrolled at the same time.

  • 文本区域在其生命周期内无法在受控或不受控之间切换。

    ¥A text area cannot switch between being controlled or uncontrolled over its lifetime.

  • 每个受控文本区域都需要一个 onChange 事件处理程序来同步更新其支持值。

    ¥Every controlled text area needs an onChange event handler that synchronously updates its backing value.


用法

¥Usage

显示文本区域

¥Displaying a text area

渲染 <textarea> 以显示文本区域。你可以使用 rowscols 属性指定其默认大小,但默认情况下用户将能够调整它的大小。要禁用调整大小,你可以在 CSS 中指定 resize: none

¥Render <textarea> to display a text area. You can specify its default size with the rows and cols attributes, but by default the user will be able to resize it. To disable resizing, you can specify resize: none in the CSS.

export default function NewPost() {
  return (
    <label>
      Write your post:
      <textarea name="postContent" rows={4} cols={40} />
    </label>
  );
}


为文本区域提供标签

¥Providing a label for a text area

通常,你会将每个 <textarea> 放在 <label> 标签中。这告诉浏览器这个标签与那个文本区域相关联。当用户点击标签时,浏览器将聚焦文本区域。它对于可访问性也很重要:当用户聚焦文本区域时,屏幕阅读器将宣布标签标题。

¥Typically, you will place every <textarea> inside a <label> tag. This tells the browser that this label is associated with that text area. When the user clicks the label, the browser will focus the text area. It’s also essential for accessibility: a screen reader will announce the label caption when the user focuses the text area.

如果你不能将 <textarea> 嵌套到 <label> 中,通过将相同的 ID 传递给 <textarea id><label htmlFor> 来关联它们 为了避免一个组件的实例之间的冲突,使用 useId 生成这样的 ID

¥If you can’t nest <textarea> into a <label>, associate them by passing the same ID to <textarea id> and <label htmlFor>. To avoid conflicts between instances of one component, generate such an ID with 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}
      />
    </>
  );
}


为文本区域提供初始值

¥Providing an initial value for a text area

你可以选择指定文本区域的初始值。将其作为 defaultValue 字符串传递。

¥You can optionally specify the initial value for the text area. Pass it as the defaultValue string.

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> 这样的初始文本。

¥Unlike in HTML, passing initial text like <textarea>Some content</textarea> is not supported.


提交表单时读取文本区域值

¥Reading the text area value when submitting a form

在你的文本区域周围添加一个 <form>,里面有一个 <button type="submit">。它将调用你的 <form onSubmit> 事件处理程序。默认情况下,浏览器会将表单数据发送到当前 URL 并刷新页面。你可以通过调用 e.preventDefault() 来覆盖该行为。使用 new FormData(e.target) 读取表单数据。

¥Add a <form> around your textarea with a <button type="submit"> inside. It will call your <form onSubmit> event handler. By default, the browser will send the form data to the current URL and refresh the page. You can override that behavior by calling e.preventDefault(). Read the form data with 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>
  );
}

注意

给你的 <textarea> 一个 name,例如 <textarea name="postContent" />。你指定的 name 将用作表单数据中的键,例如 { postContent: "Your post" }

¥Give a name to your <textarea>, for example <textarea name="postContent" />. The name you specified will be used as a key in the form data, for example { postContent: "Your post" }.

易犯错误

默认情况下,<form> 中的任何 <button> 都会提交它。这可能令人惊讶!如果你有自己的自定义 Button React 组件,请考虑返回 <button type="button"> 而不是 <button>。然后,明确地说,将 <button type="submit"> 用于应该提交表单的按钮。

¥By default, any <button> inside a <form> will submit it. This can be surprising! If you have your own custom Button React component, consider returning <button type="button"> instead of <button>. Then, to be explicit, use <button type="submit"> for buttons that are supposed to submit the form.


使用状态变量控制文本区域

¥Controlling a text area with a state variable

<textarea /> 这样的文本区域是不受控制的。即使你 传递初始值 喜欢 <textarea defaultValue="Initial text" />,你的 JSX 也只是指定了初始值,而不是现在的值。

¥A text area like <textarea /> is uncontrolled. Even if you pass an initial value like <textarea defaultValue="Initial text" />, your JSX only specifies the initial value, not the value right now.

要渲染受控文本区域,请将 value 属性传递给它。React 将强制文本区域始终具有你传递的 value。通常,你将通过声明 状态变量 来控制文本区域

¥To render a controlled text area, pass the value prop to it. React will force the text area to always have the value you passed. Typically, you will control a text area by declaring a state variable:

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!
/>
);
}

如果你想要重新渲染 UI 的某些部分以响应每次击键,这将很有用。

¥This is useful if you want to re-render some part of the UI in response to every keystroke.

{
  "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

¥If you pass value without onChange, it will be impossible to type into the text area. When you control a text area by passing some value to it, you force it to always have the value you passed. So if you pass a state variable as a value but forget to update that state variable synchronously during the onChange event handler, React will revert the text area after every keystroke back to the value that you specified.


故障排除

¥Troubleshooting

当我输入时,我的文本区域没有更新

¥My text area doesn’t update when I type into it

如果你渲染带有 value 但没有 onChange 的文本区域,你将在控制台中看到错误:

¥If you render a text area with value but no onChange, you will see an error in the console:

// 🔴 Bug: controlled text area with no onChange handler
<textarea value={something} />
Console

如错误消息所示,如果你只想 指定初始值, 传递 defaultValue

¥As the error message suggests, if you only wanted to specify the initial value, pass defaultValue instead:

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

如果你想要 用状态变量控制这个文本区域, 指定一个 onChange 处理程序:

¥If you want to control this text area with a state variable, specify an onChange handler:

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

如果该值是有意只读的,请添加 readOnly 属性以抑制错误:

¥If the value is intentionally read-only, add a readOnly prop to suppress the error:

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

我的文本区域插入符在每次击键时跳到开头

¥My text area caret jumps to the beginning on every keystroke

如果你 控制文本区域,,则必须在 onChange 期间将其状态变量更新为来自 DOM 的文本区域的值。

¥If you control a text area, you must update its state variable to the text area’s value from the DOM during onChange.

你无法将其更新为 e.target.value 以外的内容:

¥You can’t update it to something other than e.target.value:

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

你也不能异步更新它:

¥You also can’t update it asynchronously:

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

要修复你的代码,请将其同步更新到 e.target.value

¥To fix your code, update it synchronously to e.target.value:

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

如果这不能解决问题,则文本区域可能会在每次击键时从 DOM 中删除并重新添加。如果你在每次重新渲染时不小心 重置状态,就会发生这种情况。例如,如果文本区域或其父项之一始终接收不同的 key 属性,或者如果嵌套组件定义(这在 React 中是不允许的,并且会导致 “inner” 组件在每次渲染时重新挂载),就会发生这种情况。

¥If this doesn’t fix the problem, it’s possible that the text area gets removed and re-added from the DOM on every keystroke. This can happen if you’re accidentally resetting state on every re-render. For example, this can happen if the text area or one of its parents always receives a different key attribute, or if you nest component definitions (which is not allowed in React and causes the “inner” component to remount on every render).


我收到错误:“组件正在将不受控制的输入更改为受控”

¥I’m getting an error: “A component is changing an uncontrolled input to be controlled”

如果你向组件提供 value,它必须在其整个生命周期中保持为字符串。

¥If you provide a value to the component, it must remain a string throughout its lifetime.

你不能先传 value={undefined} 再传 value="some string",因为 React 不知道你是想让组件不受控制还是受控。受控组件应始终接收字符串 value,而不是 nullundefined

¥You cannot pass value={undefined} first and later pass value="some string" because React won’t know whether you want the component to be uncontrolled or controlled. A controlled component should always receive a string value, not null or undefined.

如果你的 value 来自 API 或状态变量,它可能会被初始化为 nullundefined。在这种情况下,要么最初将其设置为空字符串 (''),要么传递 value={someValue ?? ''} 以确保 value 是一个字符串。

¥If your value is coming from an API or a state variable, it might be initialized to null or undefined. In that case, either set it to an empty string ('') initially, or pass value={someValue ?? ''} to ensure value is a string.


React 中文网 - 粤ICP备13048890号