The built-in browser <textarea> component lets you render a multiline text input. 브라우저 빌트인 <textarea> 컴포넌트를 사용하면 여러줄의 텍스트 입력을 렌더링 할 수 있습니다.

<textarea />

Reference참조

<textarea>

To display a text area, render the built-in browser <textarea> component. textarea을 표시하려면 브라우저 빌트인 <textarea> 컴포넌트를 렌더링 합니다.

<textarea name="postContent" />

See more examples below. 아래에서 더 많은 예시를 확인하세요.

Props

<textarea> supports all common element props. <textarea>는 모든 공통 엘리먼트의 props를 지원합니다.

You can make a text area controlled by passing a value prop: value prop을 전달함으로써 이를 제어 컴포넌트가 되게 할 수 있습니다:

  • value: A string. Controls the text inside the text area.
    value: 문자열. textarea 내부의 텍스트를 제어합니다.

When you pass value, you must also pass an onChange handler that updates the passed value. value를 전달할 때는 전달된 value를 업데이트 하는 onChange 핸들러도 함께 전달해야 합니다.

If your <textarea> is uncontrolled, you may pass the defaultValue prop instead: <textarea>가 비제어 컴포넌트인 경우에는, 대신 defaultValue를 전달할 수 있습니다:

  • defaultValue: A string. Specifies the initial value for a text area. defaultValue: 문자열. textarea의 초기값을 지정합니다.

These <textarea> props are relevant both for uncontrolled and controlled text areas: 다음 <textarea> prop들은 비제어 및 제어 컴포넌트 모두에 영향을 미칩니다:

  • autoComplete: Either 'on' or 'off'. Specifies the autocomplete behavior. autoComplete: 'on' 혹은 'off'. 자동 완성 동작을 지정합니다.

  • autoFocus: A boolean. If true, React will focus the element on mount. autoFocus: 불리언. true일 경우 마운트시 엘리먼트에 초점이 맞춰집니다.

  • children: <textarea> does not accept children. To set the initial value, use defaultValue. children: <textarea>는 자식 요소를 받지 않습니다. 초기값을 지정하기 위해서는 defaultValue를 사용하세요.

  • cols: A number. Specifies the default width in average character widths. Defaults to 20. cols: 숫자. 표준 문자 너비를 기준으로 기본 칸 수를 지정합니다. 기본 값은 20입니다.

  • disabled: A boolean. If true, the input will not be interactive and will appear dimmed. disabled: 불리언. true일 경우, 입력이 비활성화되고 흐릿하게 표시됩니다.

  • form: A string. Specifies the id of the <form> this input belongs to. If omitted, it’s the closest parent form. form: 문자열. 이 textarea가 속한 <form>id를 지정합니다. 생략하면 가장 가까운 상위 form이 됩니다.

  • maxLength: A number. Specifies the maximum length of text. maxLength: 숫자. 텍스트의 최대 길이를 지정합니다.

  • minLength: A number. Specifies the minimum length of text. minLength: 숫자. 텍스트의 최소 길이를 지정합니다.

  • name: A string. Specifies the name for this input that’s submitted with the form. name: 문자열. 폼 제출시 해당 textarea의 이름을 지정합니다.

  • 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. onChange: 이벤트 핸들러. 제어 컴포넌트로 사용할 때 필요합니다. 사용자에 의해 입력 값이 변경되는 즉시 실행됩니다. (예: 각 키 입력시 실행됨). 브라우저의 input event처럼 동작합니다.

  • onChangeCapture: A version of onChange that fires in the capture phase. onChangeCapture: 캡쳐 단계에 실행되는 버전의 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. onInput: 이벤트 핸들러. 사용자에 의해 값이 변결될 때마다 실행됩니다. 역사적인 이유로 React에서는 일반적으로 비슷하게 작동하는 onChange를 대신 사용합니다.

  • onInputCapture: A version of onInput that fires in the capture phase. onInputCapture: 캡쳐 단계에 실행되는 버전의 onInput입니다.

  • 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. onInvalid: 이벤트 핸들러. 폼 제출시 유효성 검사에 실패하면 발생합니다. 빌트인 invalid 이벤트와는 달리, React onInvalid 이벤트는 버블이 발생합니다.

  • onInvalidCapture: A version of onInvalid that fires in the capture phase. onInvalidCapture: 캡쳐 단계에 실행되는 버전의 onInvalid입니다.

  • 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). onSelect: 이벤트 핸들러. <textarea>의 내부 선택 영역이 변경되면 발생합니다. React는 비어있는 선택과 (선택에 영향을 줄 수 있는) 편집에 대해서도 onSelect 이벤트가 발동되도록 확장했습니다.

  • onSelectCapture: A version of onSelect that fires in the capture phase. onSelectCapture: 캡쳐 단계에 실행되는 버전의 onSelect입니다.

  • placeholder: A string. Displayed in a dimmed color when the text area value is empty. placeholder: 문자열. 입력 값이 비어 있을 때 희미한 색상으로 표시됩니다.

  • readOnly: A boolean. If true, the text area is not editable by the user. readOnly: 불리언. true 일 경우 유저는 textarea을 수정할 수 없습니다.

  • required: A boolean. If true, the value must be provided for the form to submit. required: 불리언. true일 경우 form 제출시 값이 있어야 합니다.

  • rows: A number. Specifies the default height in average character heights. Defaults to 2. rows: 숫자. 표준 문자 높이를 기준으로 기본 줄 수를 지정합니다. 기본 값은 2입니다.

  • wrap: Either 'hard', 'soft', or 'off'. Specifies how the text should be wrapped when submitting a form. wrap: 'hard', 'soft', 혹은'off'. form 제출시 텍스트를 어떻게 줄바꿈할지를 지정합니다.

Caveats주의사항

  • Passing children like <textarea>something</textarea> is not allowed. Use defaultValue for initial content. <textarea>something</textarea>처럼 자식 요소를 전달하는 것은 허용되지 않습니다. 초기값은 defaultValue를 사용하세요.

  • If a text area receives a string value prop, it will be treated as controlled. 문자열 value prop을 제공하면 제어 컴포넌트로 취급됩니다.

  • 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. 생명주기 동안 제어 컴포넌트와 비제어 컴포넌트 사이를 전환할 수 없습니다.

  • Every controlled text area needs an onChange event handler that synchronously updates its backing value. 제어컴포넌트는 값을 동기적으로 업데이트 하는 onChange 이벤트 핸들러가 필요합니다.


Usage사용법

Displaying a text areatextarea 표시하기

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.

textarea를 표시하려면 <textarea>를 렌더하세요. rowscols 속성으로 기본 크기를 정할 수 있지만, 기본적으로는 사용자가 재조정할 수 있습니다. 재조정을 비활성화하려면 CSS에서resize: none을 지정하세요.
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> 태그 안에 위치시킵니다. 이렇게 하면 해당 label이 textarea와 연결되어 있음을 의미하게 됩니다. 사용자가 label을 클릭하면 브라우저가 textarea에 초점을 맞춥니다. 스크린 리더는 사용자가 textarea에 초점을 맞추면 label 캡션을 읽어주므로, 접근성을 위해서도 이렇게 하는 것이 필수적입니다.

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. <textarea><label>에 넣을 수 없는 경우에는, <textarea id><label htmlFor>에 동일한 ID를 전달하여 연결하세요. 한 컴포넌트에서 여러 인스턴스간의 충돌을 피하기 위해서는 다음과 같이 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}
      />
    </>
  );
}


Providing an initial value for a text areatextarea의 초기값 제공하기

You can optionally specify the initial value for the text area. Pass it as the defaultValue string. 선택적으로 textarea의 초기값을 지정할 수 있습니다. defaultValue에 문자열을 전달하세요.

export default function EditPost() {
  return (
    <label>
      Edit your post:
      <textarea
        name="postContent"
        defaultValue="I really enjoyed biking yesterday!"
        rows={4}
        cols={40}
      />
    </label>
  );
}

Pitfall | 함정

Unlike in HTML, passing initial text like <textarea>Some content</textarea> is not supported. HTML과 달리, 초기 텍스트를 <textarea>Some content</textarea>와 같이 자식 요소로 전달하는 것은 지원하지 않습니다.


Reading the text area value when submitting a formform 제출시 textarea 값 읽기

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). textarea를 <form>으로 감싸고, form 안에 <button type="submit">을 넣으세요. 그러면 <form onSubmit> 이벤트 핸들러가 호출됩니다. 기본적으로 브라우저는 form 데이터를 현재 URL로 전송하고 페이지를 새로고침 합니다. e.preventDefault()를 호출하여 이 동작을 재정의할 수 있습니다. form 데이터를 읽으려면 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>
  );
}

Note

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" }. <textarea name="postContent" />와 같이 <textarea>name를 지정하세요. 이렇게 지정한 name{ postContent: "Your post" }와 같이 form 데이터의 키로 사용될 것입니다.

Pitfall | 함정

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. 기본적으로 <form> 안의 어떠한 <button>이든 브라우저는 이를 제출 요청으로 인식합니다. 이러한 동작이 당황스러울 수 있습니다! 사용자정의 Button React 컴포넌트를 사용하고 있다면 <button> 대신 <button type="button">로 작성하는 것을 고려하세요. 다음 form 제출 버튼에는 <button type="submit">`을 명확하게 표시하세요.


Controlling a text area with a state variable state 변수를 사용하여 textarea 제어하기

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. <textarea />는 기본적으로 비제어 컴포넌트입니다. <textarea defaultValue="Initial text" />와 같이 초기값을 전달하더라도, JSX는 초기값만을 지정할 뿐, 현재값은 지정하지 않습니다.

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: 제어 컴포넌트로 렌더링하기 위해서는 value prop을 전달하세요. React는 textarea가 항상 전달한 value를 갖도록 강제합니다. 일반적으로 state 변수로 textarea를 제어합니다.

function NewPost() {
const [postContent, setPostContent] = useState(''); // Declare a state variable...
// state 변수 정의...
// ...
return (
<textarea
value={postContent} // ...force the input's value to match the state variable...
// ...input값이 state 변수와 일치하도록 강제...
onChange={e => setPostContent(e.target.value)} // ... and update the state variable on any edits!
// ... 그리고 수정할 때마다 state 변수를 업데이트하세요!
/>
);
}

This is useful if you want to re-render some part of the UI in response to every keystroke. 이는 모든 키 입력에 응답하여 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": {}
}

Pitfall | 함정

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. onChange 없이 value만 전달하면 textarea에 입력할 수 없습니다. textarea에 value를 전달하여 제어하면 항상 전달한 값을 갖도록 강제합니다. 따라서 state 변수를 value로 전달했지만 onChange 이벤트 핸들러에서 해당 상태 변수를 동기적으로 업데이트 하는 것을 잊어버리면, React는 키 입력시마다 textarea를 지정한 value으로 되돌립니다.


Troubleshooting문제 해결

My text area doesn’t update when I type into ittextarea에 입력해도 업데이트 되지 않습니다

If you render a text area with value but no onChange, you will see an error in the console: value는 있지만 onChange는 없는 textarea를 렌더링하면 콘솔에 에러가 표시됩니다:

// 🔴 Bug: controlled text area with no onChange handler
// 🔴 버그: 제어되는 textarea에 onChange 핸들러가 없습니다
<textarea value={something} />
Console
You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly. form 필드에 value 프로퍼티만 제공하고 onChange 핸들러는 제공하지 않았습니다. 이런 경우 읽기전용 필드가 렌더링됩니다. 필드가 변경 가능해야 하는 경우 defaultValue를 사용하십시오. 그렇지 않으면 onChange 또는 readOnly를 설정하세요.

As the error message suggests, if you only wanted to specify the initial value, pass defaultValue instead: 오류메세지에서 제안하듯이, 초기값만 지정하고 싶다면 대신 defaultValue를 사용하세요:

// ✅ Good: uncontrolled text area with an initial value
// ✅ 좋음: 초기값을 제공한 비제어 textarea
<textarea defaultValue={something} />

If you want to control this text area with a state variable, specify an onChange handler: textarea를 state 변수로 제어하고 싶다면 onChange 핸들러를 지정하세요:

// ✅ Good: controlled text area with onChange
// ✅ 좋음: onChange를 제공하는 제어 textarea
<textarea value={something} onChange={e => setSomething(e.target.value)} />

If the value is intentionally read-only, add a readOnly prop to suppress the error: 의도적으로 값을 읽기전용으로 하고자 하는 경우, readOnly prop을 추가하여 에러를 억제하세요:

// ✅ Good: readonly controlled text area without on change
// ✅ 좋음: onChange 없는 읽기전용 제어 textarea
<textarea value={something} readOnly={true} />

My text area caret jumps to the beginning on every keystroke키를 누를 때마다 커서가 처음으로 이동합니다

If you control a text area, you must update its state variable to the text area’s value from the DOM during onChange. 제어 textarea의 경우 onChange 중에 state 변수를 DOM의 값으로 업데이트해야 합니다.

You can’t update it to something other than e.target.value: e.target.value가 아닌 다른 값으로 업데이트할 수 없습니다:

function handleChange(e) {
// 🔴 Bug: updating an input to something other than e.target.value
// 🔴 버그: 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);
}

To fix your code, update it synchronously to e.target.value: 이를 수정하려면, e.target.value를 동기적으로 업데이트하세요:

function handleChange(e) {
// ✅ Updating a controlled input to e.target.value synchronously
// ✅ 제어 textarea를 e.target.value로부터 동기적으로 업데이트
setFirstName(e.target.value);
}

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). 이렇게 해도 문제가 해결되지 않는다면, 키 입력 시마다 textarea이 DOM에서 제거되었다가 다시 추가되는 상황일 수 있습니다. 렌더링할 때마다 실수로 state를 재설정하는 경우 이런 문제가 발생할 수 있습니다. 예를 들어, textarea 또는 그 부모 중 하나가 항상 다른 key 속성을 받거나, 컴포넌트 정의를 중첩하는 경우(React에서는 허용되지 않으며, 렌더링할 때마다 “내부” 컴포넌트가 다시 마운트됩니다), 이런 일이 발생할 수 있습니다.


I’m getting an error: “A component is changing an uncontrolled input to be controlled” “컴포넌트가 비제어 입력을 제어하도록 변경하고 있습니다.” 라는 오류가 발생합니다

If you provide a value to the component, it must remain a string throughout its lifetime. 컴포넌트에 value 를 제공하는 경우, 그 값은 생명주기 동안 계속 문자열로 유지되어야 합니다.

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. React는 컴포넌트를 비제어 상태로 둘지 제어 상태로 둘지 알 수 없기 때문에, value={undefined}를 먼저 전달하고 나중에 value="some string"을 전달할 수 없습니다. 제어 컴포넌트는 항상 null이나 undefined가 아닌 문자열 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. value를 API나 state 변수에서 가져오는 경우, null 또는 undefined으로 초기화될 수 있습니다. 이 경우 처음에 빈 문자열('')로 설정하거나 value={someValue ?? ''}를 전달하여 value에 문자열이 오도록 보장하세요.