[React] Controlled Component와 Uncontrolled Component

이은빈 EUNBIN·2023년 12월 3일
0

React

목록 보기
5/5
post-thumbnail

제어 컴포넌트 (Controlled Component)

  • React에 의해 값이 제어되는 입력 폼 엘리먼트(e.g. HTML의 <input>, <textarea>, <select>)다.
  • 입력 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 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>
	);
}
  • 제어 컴포넌트로 사용하면, input값은 항상 React state에 의해 결정된다.
  • 다른 UI 엘리먼트에 input값을 전달하거나 다른 이벤트 핸들러에서 값을 재설정할 수 있다.

참고 React Docs - Forms



비제어 컴포넌트 (Uncontrolled Component)

  • DOM에 신뢰 가능한 출처를 유지하며, DOM 자체에서 폼 데이터를 관리한다.
  • 모든 state 업데이트에 대한 이벤트 핸들러를 작성하는 대신 ref를 사용하여 (필요할 때) DOM에서 폼 값을 가져올 수 있다.
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 속성을 지정하여 값을 제어하도록 처리한다.
  • 컴포넌트가 마운트된 후에 defaultValue 속성의 값을 변경해도 DOM의 값은 업데이트되지 않는다.
  • React와 non-React 코드를 통합하는 것에 유용할 수 있다.

참고 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

profile
Frontend Engineer & Value Creator

0개의 댓글