일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 이슈
- 파이썬
- kubernetes
- 백준
- 이더리움
- 가상화
- k8s
- docker
- 블록체인
- react
- 프론트엔드
- next.js
- 타입스크립트
- CSS
- 알고리즘
- 자바스크립트
- 웹
- TypeScript
- 솔리디티
- 리액트
- es6
- 쿠버네티스
- JavaScript
- 클라우드
- 컴퓨터공학
- 백엔드
- node.js
- BFS
- AWS
- HTML
- Today
- Total
즐겁게, 코드
제어 컴포넌트와 비제어 컴포넌트 본문
제작중인 앱에서 사용할 컬러 팔레트 패키지를 살펴보던 중, 의아한 점이 하나 생겼습니다.
Controlled
컴포넌트에서 selectedColor
라는 변수를 갖는 것만 제외하면 둘은 거의 동일해 보이는데, 왜 Controlled - Uncontrolled 라는 이름으로 컴포넌트를 분리한 걸까요?
실제 사용할 때는 Uncontrolled
컴포넌트를 사용해도 아무 문제가 없었지만, 애매한건 확실히 짚고 넘어가야겠다는 생각에 시간을 내어 둘의 차이를 찾아보게 되었습니다.
Controlled Component (제어 컴포넌트)
제어 컴포넌트는 컴포넌트의 상태나 속성(props)으로 주어진 값을 활용하는 컴포넌트입니다.
<input>
태그를 제어 컴포넌트로 사용하는 예를 들어보면, value
값을 useState
로 관리하는 것이 대표적인 제어 컴포넌트의 예시입니다.
import { useState } from "react";
function App() {
const [inputValue, setInputValue] = useState("기본 입력값");
return (
<div className="App">
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
></input>
<div>{inputValue}</div>
</div>
);
}
export default App;
위 코드의 입력 폼에서 "찬민" 을 입력하면 당연히 "찬민" 이 화면에 보이게 되고, 입력 시마다 onChange
의 콜백을 호출함에 따라 컴포넌트가 갖는 inputValue
상태의 값도 "찬민" 이 됩니다.
즉 제어 컴포넌트에서는 데이터(상태)와 UI(폼)가 완벽하게 동기화된 상태이므로 컴포넌트가 사용자 입력에 즉시 반응할 수 있습니다.
Uncontrolled Component (비제어 컴포넌트)
그럼 어떤 컴포넌트를 비제어 컴포넌트라고 할까요?
HTML의 태그 중에서는 태그 자체적으로 상태를 갖는 경우가 있습니다.
대표적인 경우가 바로 위에서 예시로 든 <input>
태그로, 입력 폼에서 값을 입력하면 해당 값은 입력 폼 내부의 상태로 관리됩니다.
import { useRef } from "react";
function App() {
const inputRef = useRef();
return (
<div className="App">
<input type="text" ref={inputRef} defaultValue="chanmin"></input>
<button onClick={() => console.log(inputRef.current?.value)}>
클릭!
</button>
</div>
);
}
export default App;
보다시피 useState
등 컴포넌트 단위의 상태를 활용하지 않고도 태그의 참조(ref)를 활용해 입력 폼의 상태에 접근할 수 있습니다.
다만 컴포넌트의 상태가 변해야 재렌더링을 수행하는 리액트는 이를 인식하지 못해 데이터와 UI의 동기가 이루어지지 않게 됩니다.
결론
사실 리액트 공식 문서에서조차 폼을 구현할 때 제어 컴포넌트를 활용할 것을 권장하고 있습니다.
물론 개발에 정해진 길은 없겠지만, 적어도 몇몇 경우에는 반드시 제어 컴포넌트만을 사용해 구현해야 합니다.
기능 | 비제어 컴포넌트 | 제어 컴포넌트 |
폼 제출 기능을 구현할 때 | ✅ | ✅ |
제출한 입력값을 검사할 때 | ✅ | ✅ |
입력값을 실시간으로 검사할 때 | ❌ | ✅ |
제출 버튼을 입력값에 따라 커스텀할 때 | ❌ | ✅ |
한 입력 폼에 여러 데이터를 추가할 때 | ❌ | ✅ |
마지막으로 기능에 따른 컴포넌트 구현 가능여부를 표로 남기며, 다음 글로 찾아뵙도록 하겠습니다. 😆
'🎨 프론트엔드 > React.js' 카테고리의 다른 글
컴포넌트 내에서 라우팅 경로와 쿼리스트링 추출하기 (0) | 2021.04.12 |
---|---|
react-redux 로 상태 관리하기 - 01. 리덕스란 (0) | 2021.04.05 |
리액트로 첫 번째 크롬 익스텐션 빌드하기 (0) | 2021.02.19 |
useLayoutEffect 훅에 대하여 (10) | 2021.02.15 |
defaultProps에 대한 짧은 고찰 (0) | 2021.01.31 |