內建瀏覽器元件 <textarea> 可讓您渲染多行文字輸入框。

<textarea />

參考

<textarea>

要顯示文字區域,請渲染內建瀏覽器元件 <textarea>

<textarea name="postContent" />

請參閱以下更多範例。

屬性 (Props)

<textarea> 支援所有常用元件屬性

您可以透過傳遞 value 屬性來讓文字區域成為受控元件

  • value:字串。控制文字區域內的文字。

當您傳遞 value 時,您也必須傳遞一個 onChange 事件處理函式來更新傳遞的值。

如果您的 <textarea> 是不受控的,您可以改為傳遞 defaultValue 屬性

  • defaultValue:字串。指定文字區域的初始值。

以下 <textarea> 屬性與不受控和受控文字區域皆相關

  • autoComplete'on''off'。指定自動完成行為。
  • autoFocus:布林值。如果為 true,React 將在掛載時聚焦此元素。
  • children<textarea> 不接受子元件。要設定初始值,請使用 defaultValue
  • cols:數字。指定預設寬度,以平均字元寬度為單位。預設值為 20
  • disabled:一個布林值。如果為 true,則輸入框將無法互動,並且會顯示為灰色。
  • form:一個字串。指定此輸入框所屬的 <form>id。如果省略,則為最接近的父表單。
  • maxLength:一個數字。指定文字的最大長度。
  • minLength:一個數字。指定文字的最小長度。
  • name:一個字串。指定此輸入框的名稱,該名稱會隨表單提交
  • onChange:一個 Event 事件處理器 函式。對於 受控文字區域 是必需的。當輸入框的值被使用者更改時(例如,每次按鍵都會觸發),會立即觸發。行為類似於瀏覽器的 input 事件
  • onChangeCaptureonChange 的一個版本,在 捕獲階段 觸發。
  • onInput:一個 Event 事件處理器 函式。當值被使用者更改時立即觸發。由於歷史原因,在 React 中習慣使用功能類似的 onChange 來代替。
  • onInputCaptureonInput 的一個版本,在 捕獲階段 觸發。
  • onInvalid:一個 Event 事件處理器 函式。如果輸入在表單提交時驗證失敗,則觸發。與內建的 invalid 事件不同,React 的 onInvalid 事件會冒泡。
  • onInvalidCaptureonInvalid 的一個版本,在 捕獲階段 觸發。
  • onSelect:一個 Event 事件處理器 函式。<textarea> 內的選取範圍更改後觸發。React 擴展了 onSelect 事件,使其也能在選取範圍為空和編輯時觸發(這可能會影響選取範圍)。
  • onSelectCaptureonSelect 的一個版本,在 捕獲階段 觸發。
  • placeholder:一個字串。當文字區域值為空時,以灰色顯示。
  • readOnly:一個布林值。如果為 true,則文字區域不可由使用者編輯。
  • required:一個布林值。如果為 true,則表單提交時必須提供值。
  • rows:一個數字。指定預設高度,以平均字元高度為單位。預設值為 2
  • wrap'hard''soft''off'。指定提交表單時應如何換行文字。

注意事項

  • 不允許像 <textarea>something</textarea> 這樣傳遞子元素。使用 defaultValue 來設定初始內容
  • 如果文字區域收到一個字串 value 屬性,它將被視為受控的
  • 文字區域不能同時是受控的和非受控的。
  • 文字區域在其生命週期內不能在受控和非受控之間切換。
  • 每個受控的文字區域都需要一個 onChange 事件處理程序,用於同步更新其背後的值。

用法

顯示文字區域

渲染 <textarea> 來顯示文字區域。您可以使用 rowscols 屬性指定其預設大小,但預設情況下,使用者可以調整其大小。要禁用調整大小功能,您可以在 CSS 中指定 resize: none

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


提供文字區域的標籤

通常,您會將每個 <textarea> 放在 <label> 標籤內。這會告訴瀏覽器此標籤與該文字區域相關聯。當使用者點擊標籤時,瀏覽器將聚焦文字區域。這對於無障礙功能也很重要:當使用者聚焦文字區域時,螢幕閱讀器會朗讀標籤標題。

如果您無法將 <textarea> 嵌套到 <label> 中,請將相同的 ID 傳遞給 <textarea id><label htmlFor> 來關聯它們。為了避免一個組件的實例之間發生衝突,請使用 useId 生成此類 ID。

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>一些內容</textarea>


提交表單時讀取文字區域值

在您的 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>
  );
}

注意事項

為您的 <textarea> 指定一個 name,例如 <textarea name="postContent" />。您指定的 name 將在表單數據中用作鍵,例如 { postContent: "您的貼文" }

陷阱

預設情況下,<form> 內的 *任何* <button> 都會提交它。這可能會讓人感到意外!如果您有自己的自定義 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!
/>
);
}

如果您希望 UI 的某些部分在每次按鍵時都能重新渲染,這將很有用。

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


疑難排解

我的文字區域在我輸入時沒有更新 ...

如果您渲染一個帶有

// 🔴 Bug: controlled text area with no onChange handler
<textarea value={something} />
主控台
您提供了一個 如錯誤訊息所示,如果您只想 指定*初始*值,請改為傳遞
// ✅ Good: uncontrolled text area with an initial value
<textarea defaultValue={something} />

如果您想 使用狀態變數控制此文字區域,請指定一個

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

如果該值有意唯讀,請新增一個

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

我的文字區域插入符號在每次按鍵時都會跳到開頭 ...

如果您 控制文字區域,則必須在 您無法將其更新為

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

要修復您的程式碼,請將其同步更新為

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

如果這沒有解決問題,則可能是文字區域在每次按鍵時都會從 DOM 中移除並重新新增。如果您不小心在每次重新渲染時都 重置狀態,就會發生這種情況。例如,如果文字區域或其父元件之一始終收到不同的

我收到一個錯誤:「元件正在將非受控輸入變更為受控」

如果您提供 value 給元件,它在其生命週期內必須保持為字串。

您不能先傳遞 value={undefined},然後再傳遞 value="some string",因為 React 無法得知您希望元件是非受控還是受控。受控元件應該始終接收字串 value,而不是 nullundefined

如果您的 value 來自 API 或狀態變數,它可能初始化為 nullundefined。在這種情況下,請將其初始設定為空字串 (''),或傳遞 value={someValue ?? ''} 以確保 value 是字串。

上一頁<select>
下一頁<link>