0. 개요
- 리액트는 <input>, <textarea>, <select> 와 같이 입력을 받을 수 있는 폼 요소들을 제어 컴포넌트와 비제어 컴포넌트로 구분하고 있다.
1. 제어컴포넌트
제어 컴포넌트는 상태(state)와 함께 사용되며, 해당 컴포넌트의 상태에 의해 값이 제어된다.
이 상황은 마치 입력 폼 요소가 이벤트 핸들러 외에 다른 누군가에 의해 변경될 수 없도록 제어하고 있는 것 같다.
이렇게 입력 폼 요소의 value 속성을 지정하여 값을 제어할 수 있는 컴포넌트를 제어 컴포넌트라고 한다.
즉, 사용자의 입력을 받는 컴포넌트에 event 객체를 이용해 setState()로 값을 저장하는 방식을 제어 컴포넌트 방식이라 한다.
=> 제어 컴포넌트는 사용자가 입력한 값과 저장되는 값이 실시간으로 동기화된다.
export default function App() {
const [input, setInput] = useState("");
const onChange = (e) => {
setInput(e.target.value);
};
return (
<div className="App">
<input onChange={onChange} />
</div>
);
}
✏️제어 컴포넌트를 사용할 때 문제점
- 제어 컴포넌트는 UI의 입력한 데이터 상태와 저장된 데이터 상태가 항상 일치한다.
=> 즉, 사용자가 입력하는 모든 데이터가 동기화가 된다는 것이다.
아래와 같이 불필요한 단어 입력시에도 값이 갱신되어버린다. 이는 불필요한 리렌더링, 불필요한 api 요청으로 자원낭비 문제로 연결될 수 있다.
ㅇ
아
안
안ㄴ
안녀
안녕
안녕ㅎ
안녕하
안녕핫
안녕하
안녕하세
안녕하셍
안녕하세
안녕하세요
이러한 경우 디바운스를 이용해서 불필요한 렌더링을 막을 수 있다.
(디바운스 : 연속으로 호출되는 함수들 중 마지막에 호출되는 함수 만 실행되도록 하는 것)
✏️제어 컴포넌트는 언제 사용할까?
- 입력 받은 값을 바로바로 유효성 검사를 해야할 때 사용하는 경우(사용자가 입력할 때마다 state값이 동기화되므로 최신값을 유지하는 특성에 따라 현재 input의 value 가 유효한지 안 한지에 대한 검사를 실시간으로 확인할 수 있다)
- 실시간으로 input을 검사해야하는 경우, 마지막으로 조건에 따라 버튼이 활성화 되어야 하는경우
2. 비제어 컴포넌트 (제어컴포넌트와 비교해보기)
리액트의 상태(state)와 직접 연결되지 않으며, 일반적으로 ref 를 사용하여 DOM 요소에 직접 접근한다.
React 가 Form 의 입력값을 제어하지 않고(리액트의 상태를 직접 관리하지 않고), 전통적인 HTML Form Element 를 다루는 것처럼 DOM 요소를 직접 다룬다.
제어 컴포넌트의 경우 사용자가 입력을 하는 액션을 취할때마다 리렌더링을 발생시키는 반면, 비제어 컴포넌트는 리렌더링을 발생시키지도 않고 값을 동기화 시키지도 않는다.
🔸제어 컴포넌트
import React, { useState } from "react";
import { UncontrolledComponent } from "./uncontrolled";
// 제어 컴포넌트
export default function ControlledComponent() {
const [value, setValue] = useState("");
const handleChange = (event) => {
setValue(event.target.value);
console.log("제어", value);
console.log("제어 렌더링!");
};
return (
<>
<h1>제어컴포넌트</h1>
<input type="text" value={value} onChange={handleChange} />
<UncontrolledComponent />
</>
);
}
🔸비제어 컴포넌트
import React, { useRef } from "react";
export function UncontrolledComponent() {
const inputRef = useRef(null);
const handleChange = () => {
console.log("비제어", inputRef.current.value);
};
console.log("비제어 렌더링!");
return (
<>
<h1>비제어컴포넌트</h1>
<input type="text" ref={inputRef} onChange={handleChange} />
</>
);
}
아래와 같이 직접 DOM 을 불러와서 콘솔창에 출력하는건 출력되지만 console.log('비제어 렌더링') 은 한번만 출력되는 것을 볼 수 있다. 즉, 비제어 컴포넌트는 실시간으로 렌더링이 새롭게 되지 않는다.
3. 제어컴포넌트 VS 비제어컴포넌트
기능 | 제어컴포넌트 | 비제어 컴포넌트 |
일회성 정보 검색 (예: 제출) | O | O |
제출 시 값 검증 | O | O |
실시간으로 필드값의 유효성 검사 | O | X |
조건부로 제출 버튼 비활성화 (disabled) | O | X |
실시간으로 입력 형식 적용하기 (숫자만 가능하게 등) | O | X |
동적 입력 | O | X |
즉각적으로, 실시간으로 값에 대한 피드백이 필요하다 > 제어 컴포넌트 사용
즉각적인 피드백이 불필요하고 제출시에만 값이 필요하다, 불필요한 렌더링과 값 동기화가 싫다 > 비제어 컴포넌트 사용
참고자료
https://dkrnfls.tistory.com/248
https://www.youtube.com/watch?v=PBgQKK6nelo
'프론트엔드 개발 > React' 카테고리의 다른 글
Redux-Toolkit 상태관리 라이브러리 사용법 (0) | 2023.08.30 |
---|---|
리액트) state의 모든 것 (props/state/로컬/전역/서버상태) (0) | 2023.08.16 |
React-Query 사용 방법 (0) | 2023.07.11 |
React) setState 함수의 모든 것 (0) | 2023.07.11 |
React) 커스텀 훅(Custom Hook) 만들기 (0) | 2023.07.10 |