[React] 제어, 비제어 컴포넌트

김채운·2023년 2월 11일
0

React

목록 보기
16/26

🐻 제어 컴포넌트

제어 컴포넌트는 HTML에서 input, textarea, select와 같은 폼 엘리먼트에서 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트합니다. React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 setState()에 의해 업데이트됩니다.
React에 의해 값이 제어되는 입력 폼 엘리먼트를 “제어 컴포넌트 (controlled component)“라고 합니다.

제어 컴포넌트에서 input의 value는 React의 state에 의해 결정되는데, 이를 리액트 공식문서에서는 다음과 같이 표현한다. 👇

React state는 신뢰 가능한 단일 출처 (single source of truth)가 됩니다.

export default function App() {
  const [input, setInput] = useState("");
  const onChange = (e) => {
    setInput(e.target.value);
  };

  return (
    <div className="App">
      <input onChange={onChange} value={input}/>
    </div>
  );
}
  • input에 사용자가 데이터를 입력하면
  • 입력할 때마다, onChange 이벤트 핸들러가 실행되고
  • setInput()이 input의 값을 실시간으로 입력되고 있는 데이터로 변경 시킨다. (setState가 state를 변경시킴)
  • 그렇게 변경된 state 값은 input 태그 안에 있는 value에 할당된다.

❗제어 컴포넌트는 사용자 입력 폼에 사용자가 입력을 하면 입력한 값과 저장되는 값이 실시간으로 동기화된다. 따라서 input의 유효성 검사를 할 때 제어 컴포넌트가 용이하다. 항상 최신 값을 유지하는 특성에 따라 현재 input의 value가 유효한지 안 한 지에 대한 검사를 실시간으로 할 수 있다.

❗제어 컴포넌트는 사용자가 입력을 할때마다 리렌더링이 발생한다. 그리고 불필요한 단어를 입력했을 때도 값이 입력되고 state에 반영되는데, 이는 불필요한 리렌더링, 불필요한 api요청으로 인한 자원 낭비 문제로도 연결 될 수 있다.

🐻 비제어 컴포넌트

비제어 컴포넌트는 자바스크립트와 비슷하다. 제어 컴포넌트와는 다르게 ref라는 hook을 이용해서 form에 접근한다.
자바스크립트에서는 submit button을 통해서 form을 제출해야 value 값을 받아올 수 있었는데 그 방식과 다르지 않다. 제어 컴포넌트는 실시간으로 입력하는 데이터가 동기화 된다면 비제어 컴포넌트는 제출버튼을 클릭해야 입력 데이터를 받을 수 있다.

export default function App() {
  const inputRef = useRef(); // ref 사용
  const onClick = () => {
    console.log(inputRef.current.value);
  };

  return (
    <div className="App">
      <input ref={inputRef} />
      <button type="submit" onClick={onClick}>
        전송
      </button>
    </div>
  );
}
  • input에 사용자가 데이터를 입력하고
  • '전송' 버튼을 클릭한다.
  • 그럼 ref를 통해 current.value 값을 받아볼 수 있다.

JS에서는 querySelector를 통해서 addEventListener를 실행시켰는데, 이와 방식이 비슷하다.

❗제어 컴포넌트와는 다르게 실시간으로 동기화 되지 않는다. 버튼을 클릭해봐야 input에 입력된 값을 받아볼 수 있다.

❗제어 컴포넌트와는 다르게 리렌더링이 계속해서 발생하지는 않지만, 하지만 그만큼 비제어 컴포넌트는 사용자 입력의 가장 최신 값에 접근하기 힘들다는 특성이 있다.

❗ref를 사용하는데 왜 React를 사용해서 제어하지 않는 '비제어 컴포넌트'라고 하는 걸까? 그 이유는, inputRef.current.value 이 코드는 단순히 DOM 엘리먼트에 접근하는 거지 React가 사용된 게 아니다. 그저 일반 DOM API를 사용해서 인풋 DOM 노드의 DOM 노드 값을 설정하는 것이다. 제어 컴포넌트처럼 useState 등 컴포넌트 단위의 상태를 활용해서 state로 값을 관리하지 않기 때문에 비제어 컴포넌트라고 한다.

둘 중에 어떤 걸 사용해야 할까?

❗ 공식문서에서는 폼을 구현할 때 제어 컴포넌트를 활용할 것을 권장하고 있다. 그래서 웬만하면 제어 컴포넌트를 사용 하겠지만, 상황에 맞게 사용하면 된다고 생각한다.
실시간으로 유효성 검사가 필요한 경우에는 '제어 컴포넌트'를 사용하는 게 좋을 것이고, 불필요한 재렌더링을 줄이고 싶고 제출 시에만 값이 필요할 때는 '비제어 컴포넌트'를 사용하면 되는 일이니 상황에 맞게 고민해보고 사용하자!

출처

0개의 댓글