<input>
, <textarea>
, <select>
)다.setState()
에 의해 업데이트된다.function NameForm() {
const [nameValue, setNameValue] = useState('');
const handleChange = (event) => {
setNameValue(event.target.value);
}
const handleSubmit = (event) => {
alert("A name was submitted: " + nameValue);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
/**
* @see
* value 속성: 폼 엘리먼트에 설정되므로 항상 nameValue state로 관리된다. - 신뢰 가능한 단일 출처(Single Source of Truth)
* handleChange: 사용자가 입력할 때 보여지는 값을 업데이트한다.
*/
Name: <input type="text" value={nameValue} onChange={handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
function NameForm() {
const inputRef = useRef();
const handleSubmit = (event) => {
alert("A name was submitted: " + inputRef.current.value);
event.preventDefault();
}
return (
<form onSubmit={handleSubmit}>
<label>
/**
* @see
* ref 속성: 폼 엘리먼트의 value 속성값을 관리한다. -> 리액트 렌더링 라이프사이클에서 폼 엘리먼트의 value 속성은 DOM의 value로 오버라이드된다. (DOM의 값을 우선시한다.)
* defaultValue 속성: input의 value값을 제어하기 위해 사용한다.
*/
Name: <input defaultValue="Bob" type="text" ref={inputRef} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
value
대신 defaultValue
속성을 지정하여 값을 제어하도록 처리한다.참고 React Docs - Uncontrolled Components
기능 | 제어 컴포넌트 | 비제어 컴포넌트 |
---|---|---|
일회성 값 검색 (e.g. onSubmit ) | ✅ | ✅ |
제출 시 유효성 검사 | ✅ | ✅ |
실시간 필드 유효성 검사 | ✅ | ❌ |
조건 | ✅ | ❌ |
조건부 submit 버튼 비활성화 | ✅ | ❌ |
input 형식 강제화 | ✅ | ❌ |
하나의 데이터에 대한 여러 input들 | ✅ | ❌ |
동적인 input | ✅ | ❌ |
UI 피드백 측면에서 폼이 굉장히 간단하다면 refs를 사용한 비제어 컴포넌트를 사용해도 문제 없으며, 비제어 컴포넌트를 사용하다 언제든지 제어 컴포넌트로 변경할 수도 있다.
많은 아티클에서의 "setState
를 사용하면 안된다", 공식 문서에서의 "ref
는 나쁘다".. 등등 다양한 주장들이 있지만, 제어 컴포넌트와 비제어 컴포넌트는 각각의 장점이 있기 때문에 상황에 맞게 사용해야 한다.
참고 Controlled and uncontrolled form inputs in React don't have to be complicated