<input />
참조
<input>
<input name="myInput" />
Props
<input>
은 모든 공통 엘리먼트 prop을 지원합니다.다음 props 중 하나를 전달하여 input을 제어할 수 있습니다:
checked
: 불리언. 체크박스 input 또는 라디오 버튼의 선택 여부를 제어합니다.
value
: 문자열. 텍스트 input의 텍스트를 제어합니다. (라디오 버튼의 경우 해당 form data를 지정합니다).
위 둘 중 하나를 전달할 때, 전달된 값을 업데이트하는
onChange
핸들러도 함께 전달해야 합니다.다음
<input>
props는 비제어 input에만 관련이 있습니다:defaultChecked
: 불리언.type="checkbox"
및type="radio"
의 기본값을 특정합니다.
defaultValue
: 문자열. 텍스트 input의 기본값을 특정합니다.
다음
<input>
props는 비제어 및 제어 input 모두에 해당합니다:accept
: 문자열.type="file"
input에 허용되는 파일 형식을 지정합니다.
alt
: 문자열.type="image"
input의 대체 이미지 텍스트를 지정합니다.
capture
: 문자열.type="file"
input으로 캡쳐할 미디어(마이크, 비디오, 카메라)를 지정합니다.
autoComplete
: 문자열. 가능한 자동완성 동작을 지정합니다.
autoFocus
: 불리언.true
이면 엘리먼트가 마운트될 때 초점을 맞춥니다.
dirname
: 문자열. 엘리먼트의 방향성에 대한 폼 필드 이름을 지정합니다.
disabled
: 불리언.true
이면 해당 input은 상호작용할 수 없으며 흐릿하게 보여집니다.
children
:<input>
은 자식을 받지 않습니다.
form
: 문자열. 이 input이 속한<form>
의id
를 지정합니다. 이 prop이 없으면 상위의 가장 가까운 form이 됩니다.
formAction
: 문자열.type="submit"
및type="image"
에 대해 상위<form action>
을 덮습니다.
formEnctype
: 문자열.type="submit"
및type="image"
에 대해 상위<form enctype>
을 덮습니다.
formMethod
: 문자열.type="submit"
및type="image"
에 대해 상위<form method>
을 덮습니다.
formNoValidate
: 문자열.type="submit"
및type="image"
에 대해 상위<form noValidate>
을 덮습니다.
formTarget
: 문자열.type="submit"
및type="image"
에 대해 상위<form target>
을 덮습니다.
height
: 문자열.type="image"
의 이미지 높이를 지정합니다.
list
: 문자열. autocomplete 옵션들과 함께<datalist>
의id
를 지정합니다.
max
: 숫자. 숫자타입 및 날짜시간 input의 최대값을 지정합니다.
maxLength
: 숫자. 텍스트 및 기타 input의 최대 길이를 지정합니다.
min
: 숫자. 숫자타입 및 날짜시간 input의 최솟값을 지정합니다.
minLength
: 숫자. 텍스트 및 기타 input의 최소 길이를 지정합니다.
multiple
: 불리언.type="file"
및type="email"
에 대해 여러 값을 허용할지 여부를 지정합니다.
onChange
:Event
핸들러 함수. 제어 input에서 필수입니다. 사용자가 input의 값을 변경하면 즉시 호출됩니다(예: 키 입력시마다 발생). 브라우저input
이벤트처럼 동작합니다.
onChangeCapture
: 캡쳐 단계에서 실행되는 버전의onChange
입니다.
onInput
:Event
핸들러 함수. 사용자가 값을 변경하면 즉시 호출됩니다. 역사적인 이유로 React에서는 비슷한 방식으로 작동하는onChange
를 대신 사용하는 것이 일반적입니다.
onInputCapture
: 캡쳐 단계에서 실행되는 버전의onInput
입니다.
onInvalid
:Event
핸들러 함수. 폼 제출시 input이 유효성 검사에 실패하면 호출됩니다. 빌트인invalid
이벤트와 달리, React의onInvalid
이벤트는 버블을 발생시킵니다.
onInvalidCapture
: 캡쳐 단계에서 실행되는 버전의onInvalid
입니다.
onSelect
:Event
핸들러 함수.<input>
내부의 선택이 변경되면 호출됩니다. React는 선택이 빈 경우와 (선택에 영향을 미칠 수 있는) 편집에 대해서도onSelect
이벤트가 호출되도록 확장합니다.
onSelectCapture
:캡쳐 단계에서 실행되는 버전의onSelect
입니다.
pattern
: 문자열.value
가 일치해야 하는 패턴을 지정합니다.
placeholder
: 문자열. input 값이 비어있을 때 희미한 색상으로 표시되는 텍스트입니다.
readOnly
: 불리언.true
이면 이 input은 사용자가 편집할 수 없습니다.
required
: 불리언.true
이면 값을 입력해야만 폼을 제출할 수 있습니다.
size
: 숫자. 너비 설정과 유사하지만, 단위는 컨트롤에 따라 다릅니다.
src
: 문자열.type="image"
input의 이미지 소스를 지정합니다.
step
: 양수 또는 문자열'any'
. 유효한 값 사이의 거리를 지정합니다.
type
: 문자열. input type 중 하나.
width
: 문자열.type="image"
input의 이미지 너비를 지정합니다.
주의사항
- 체크박스는
value
(또는defaultValue
)가 아닌checked
(또는defaultChecked
)가 필요합니다.
- 텍스트 input이 문자열
value
prop을 받으면 제어된 것으로 처리됩니다.
- 체크박스나 라디오 버튼이 불리언
checked
prop을 받으면 제어된 것으로 처리됩니다.
- input은 동시에 제어되거나 제어되지 않을 수 없습니다.
- input은 수명 동안 제어되거나 제어되지 않는 상태로 전환될 수 없습니다.
- 제어되는 모든 입력에는
onChange
이벤트 핸들러가 필요하며, 이 핸들러는 지원 값을 동기적으로 업데이트합니다.
사용법
다양한 유형의 input 표시하기
input을 표시하려면
<input>
컴포넌트를 렌더링합니다. 기본적으로 텍스트 input이 됩니다. 체크박스의 경우 type="checkbox"
, 라디오 버튼의 경우 type="radio"
또는 다른 input 유형 중 하나를 전달할 수 있습니다.input에 대한 label 제공하기
일반적으로 모든
<input>
은 <label>
태그 안에 배치됩니다. 이는 이 label이 해당 input과 연결되어 있음을 브라우저에 알려줍니다. 사용자가 label을 클릭하면 브라우저가 자동으로 input에 초점을 맞춥니다. 이는 접근성 측면에서도 필수적입니다: 사용자가 관련 input에 초점을 맞추면 스크린 리더가 label 캡션을 알립니다.<input>
을 <label>
에 중첩할 수 없는 경우 동일한 ID를 <input id>
및 <label htmlFor>
.에 전달하여 연결합니다. 한 컴포넌트의 여러 인스턴스 간에 충돌을 피하려면 useId
를 사용하여 이러한 ID를 생성하십시오.input에 대한 초기값 제공하기
선택적으로 모든 input의 초기값을 지정할 수 있습니다. 텍스트 input의 경우
defaultValue
문자열로 전달합니다. 체크박스와 라디오 버튼은 불리언 타입인 defaultChecked
으로 초기값을 대신 지정해야 합니다.form 제출 시 input 값 읽기
input 주위에
<form>
을 추가하고 그 안에 <button type="submit">
을 추가합니다. 그러면 <form onSubmit>
이벤트 핸들러가 호출됩니다. 기본적으로 브라우저는 form 데이터를 현재 URL로 전송하고 페이지를 새로 고칩니다. e.preventDefault()
를 호출하여 이 동작을 재정의할 수 있습니다. new FormData(e.target)
로 form 데이터를 읽습니다.Note
모든
<input>
에 name
을 지정하세요(예: <input name="firstName" defaultValue="Taylor" />
). 지정한 name
은 form 데이터에서 키로 사용됩니다(예: { firstName: "Taylor" }
).Pitfall | 함정
기본적으로
<form>
안에 있는 모든 <button>
은 제출됩니다. 의외일 수 있습니다! 커스텀 Button
React 컴포넌트가 있는 경우 <button>
대신 <button type="button">
을 반환하는 것을 고려하세요. 그런 다음 form을 제출해야 하는 버튼에 <button type="submit">
을 사용하세요.state 변수로 input 제어하기
<input />
과 같은 input은 제어되지 않습니다. <input defaultValue="Initial text" />
와 같이 초기값을 전달하더라도 JSX는 초기값만 지정합니다. 현재 값이 무엇이어야 하는지는 제어하지 않습니다.제어된 input을 렌더링하려면 value
prop을 전달하세요(체크박스와 라디오의 경우 checked
). React는 입력이 항상 전달한 value
를 갖도록 강제합니다. 보통은 state 변수를 선언하여 이를 수행합니다.function Form() { const [firstName, setFirstName] = useState(''); // Declare a state variable... // state 변수 정의... // ... return ( <input value={firstName} // ...force the input's value to match the state variable... // ...input값이 state 변수와 일치하도록 강제... onChange={e => setFirstName(e.target.value)} // ... and update the state variable on any edits! // ... 그리고 수정할 때마다 state 변수를 업데이트하세요! /> ); }
어차피 state가 필요한 경우(예: 편집할 때마다 UI를 다시 렌더링해야 하는 경우) 제어 input이 적합합니다:
function Form() { const [firstName, setFirstName] = useState(''); return ( <> <label> First name: <input value={firstName} onChange={e => setFirstName(e.target.value)} /> </label> {firstName !== '' && <p>Your name is {firstName}.</p>} ...
다양한 방법으로 input state를 조정하는 기능을 제공하려는 경우(예: 버튼을 클릭하는 등)에도 유용합니다:
function Form() { // ... const [age, setAge] = useState(''); const ageAsNumber = Number(age); return ( <> <label> Age: <input value={age} onChange={e => setAge(e.target.value)} type="number" /> <button onClick={() => setAge(ageAsNumber + 10)}> Add 10 years </button>
제어 컴포넌트에 전달하는
value
는 undefined
또는 null
이어서는 안됩니다. 초기값을 비워야 하는 경우(아래의 firstName
필드와 같이) state 변수를 빈 문자열(''
)로 초기화하세요.Pitfall | 함정
onChange
없이 value
를 전달하면 input에 입력이 불가능합니다. 어떤 value
를 전달해서 input을 제어하면 항상 전달한 값을 갖도록 강제하게 됩니다. 따라서 state 변수를 value
로 전달했지만 onChange
이벤트 핸들러에서 해당 state 변수를 동기적으로 업데이트하는 것을 잊어버린 경우, React는 모든 키 입력 후 input을 사용자가 지정한 value
로 되돌립니다.모든 키 입력 리렌더링 최적화하기
제어 input을 사용할 때는 모든 키 입력에 state를 설정합니다. state가 포함된 컴포넌트가 큰 트리를 다시 렌더링하면 속도가 느려질 수 있습니다. 리렌더링 성능을 최적화할 수 있는 몇 가지 방법이 있습니다.
예를 들어, 모든 키 입력 시 모든 페이지 콘텐츠를 다시 렌더링하는 form으로 시작한다고 가정해 보겠습니다:
function App() { const [firstName, setFirstName] = useState(''); return ( <> <form> <input value={firstName} onChange={e => setFirstName(e.target.value)} /> </form> <PageContent /> </> ); }
PageContent />
는 input state에 의존하지 않으므로 input state를 자체 컴포넌트로 이동할 수 있습니다:function App() { return ( <> <SignupForm /> <PageContent /> </> ); } function SignupForm() { const [firstName, setFirstName] = useState(''); return ( <form> <input value={firstName} onChange={e => setFirstName(e.target.value)} /> </form> ); }
이제 모든 키 입력에 대해
SignupForm
만 리렌더링하므로 성능이 크게 향상됩니다.
리렌더링을 피할 방법이 없는 경우(예: PageContent
가 검색 input 값에 의존하는 경우), useDeferredValue
를 사용하면 대규모 리렌더링 중에도 제어된 input의 반응성을 유지할 수 있습니다.문제 해결
텍스트 input에 타이핑해도 업데이트되지 않습니다
input에
onChange
없이 value
만 지정하여 렌더링하면 콘솔에 에러가 표시됩니다:// 🔴 Bug: controlled text input with no onChange handler // 🔴 버그: 제어 텍스트 input에 onChange 핸들러가 없습니다 <input value={something} />
폼 필드에
onChange
핸들러가 없이 value
prop만 제공했습니다. 이러면 읽기 전용 필드가 렌더링됩니다. 필드가 변경되어야 하는 경우 defaultValue
를 사용하세요. 그렇지 않으면 onChange
또는 readOnly
를 설정하세요.// ✅ Good: uncontrolled input with an initial value // ✅ 좋음: 초기값을 제공한 비제어 input <input defaultValue={something} />
이 input을 state 변수로 제어하고 싶다면
onChange
핸들러를 지정하세요:// ✅ Good: controlled input with onChange // ✅ 좋음: onChange가 있는 제어 input <input value={something} onChange={e => setSomething(e.target.value)} />
의도적으로 값을 읽기전용으로 하려는 경우,
readOnly
prop을 추가하여 오류를 억제하세요:// ✅ Good: readonly controlled input without onChange // ✅ 좋음: onChange가 없는 읽기 전용 제어 input <input value={something} readOnly={true} />
체크박스를 클릭해도 업데이트되지 않습니다
체크박스에
onChange
없이 checked
만 지정하여 렌더링하면 콘솔에 에러가 표시됩니다:// 🔴 Bug: controlled checkbox with no onChange handler // 🔴 버그: 제어 체크박스에 onChange 핸들러가 없습니다 <input type="checkbox" checked={something} />
폼 필드에
onChange
핸들러가 없이 checked
prop만 제공했습니다. 이러면 읽기 전용 필드가 렌더링됩니다. 필드가 변경되어야 하는 경우 defaultChecked
를 사용하세요. 그렇지 않으면 onChange
또는 readOnly
를 설정하세요.// ✅ Good: uncontrolled checkbox with an initial value // ✅ 좋음: 초기값을 제공한 비제어 체크박스 <input type="checkbox" defaultChecked={something} />
이 체크박스를 state 변수로 제어하고 싶다면
onChange
핸들러를 지정하세요:// ✅ Good: controlled checkbox with onChange
// ✅ 좋음: onChange가 있는 제어 체크박스
<input type="checkbox" checked={something} onChange={e => setSomething(e.target.checked)} />
Pitfall | 함정
체크박스의 경우
e.target.value
가 아닌 e.target.checked
를 읽어야 합니다.의도적으로 값을 읽기전용으로 하려는 경우,
readOnly
prop을 추가하여 오류를 억제하세요:// ✅ Good: readonly controlled checkbox without on change // ✅ 좋음: onChange가 없는 읽기 전용 제어 체크박스 <input type="checkbox" checked={something} readOnly={true} />
키를 누를 때마다 커서가 처음으로 이동합니다
제어 input의 경우
onChange
중에 state 변수를 DOM의 값으로 업데이트해야 합니다.e.target.value
(체크박스의 경우 e.target.checked
)가 아닌 다른 값으로 업데이트할 수 없습니다:function handleChange(e) { // 🔴 Bug: updating an input to something other than e.target.value // 🔴 버그: 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 // ✅ 제어 input을 e.target.value로부터 동기적으로 업데이트 setFirstName(e.target.value); }
이렇게 해도 문제가 해결되지 않는다면, 키 입력 시마다 input이 DOM에서 제거되었다가 다시 추가되는 상황일 수 있습니다. 렌더링할 때마다 실수로 state를 재설정하는 경우 이런 문제가 발생할 수 있습니다. 예를 들어, input 또는 그 부모 중 하나가 항상 다른
key
속성을 받거나, 컴포넌트 정의를 중첩하는 경우(React에서는 허용되지 않으며, 렌더링할 때마다 “내부” 컴포넌트가 다시 마운트됩니다), 이런 일이 발생할 수 있습니다.“컴포넌트가 비제어 입력을 제어하도록 변경하고 있습니다.” 라는 오류가 발생합니다
컴포넌트에
value
를 제공하는 경우, 그 값은 생명주기 동안 계속 문자열로 유지되어야 합니다.React는 컴포넌트를 비제어 상태로 둘지 제어 상태로 둘지 알 수 없기 때문에,
value={undefined}
를 먼저 전달하고 나중에 value="some string"
을 전달할 수 없습니다. 제어 컴포넌트는 항상 null
이나 undefined
가 아닌 문자열 value
를 받아야 합니다.value
를 API나 state 변수에서 가져오는 경우, null
또는 undefined
으로 초기화될 수 있습니다. 이 경우 처음에 빈 문자열(''
)로 설정하거나 value={someValue ?? ''}
를 전달하여 value
에 문자열이 오도록 보장하세요.마찬가지로, 체크박스에
checked
를 전달할 때는 항상 불리언인지를 확인하세요.