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

정진범·2024년 3월 2일


NEXTSTEP TDD, 클린 코드 with React 3기를 시작하게 되었습니다. 현재 2주차가 진행 중이면 미션을 수행 중인데 그 과정에서 배운 것들과 새롭게 알게된 것을 글로 작성해보려고 한다. 이번 글은 제어 컴포넌트와 비제어 컴포넌트에 대해 알아보는 글을 작성하려고 합니다.

제어 컴포넌트와 비제어 컴포넌트에 설명하기 위해서는 신뢰 가능한 단일 출처에 대해 짚고 가야하기 때문에 알아려고 합니다.

📌 신뢰 가능한 단일 출처 (Single Source Of Truth)

신뢰 가능 단일 출처란 하나의 상태는 한 곳에만 존재 해야한다. 라는 뜻입니다.

input 태그를 예시로 들어보겠습니다.

사용자가 input 태그에 값을 입력하면 value Attribute는 최신화 된 값을 가지며 value Attribute의 값을 사용할때 신뢰 가능합니다. 그리고 input 태그의 value Attribute는 유일합니다 따라서 value Attribute는 신뢰 가능한 단일 출처임을 알 수 있습니다.

제어 컴포넌트는 value Attribute의 값을 React의 상태(state)로 관리하고 제어함으로 신뢰 가능한 단일 출처임을 보장합니다.

사용자 입력한 값은 value Attribute 저장됩니다. value Attribute는 DOM안에 있으므로 사용자가 입력한 값이 DOM에 저장됩니다. 비제어 컴포넌트는 ref를 사용하여 DOM에 접근하여 저장된 값을 가져옴으로 신뢰 가능한 단일 출처임을 보장합니다.

📌 Controlled Components(제어 컴포넌트)

제어 컴포넌트(Controlled Component)는 React에서 폼 요소나 다른 입력 요소에 대한 상태를 React의 상태(state)에 의해 제어되는 컴포넌트를 가리킵니다. 이는 사용자의 입력에 반응하여 React의 상태를 업데이트하고, 그에 따라 화면을 다시 렌더링하는 방식입니다.

input value값을 React의 상태(state)로 관리하고 제어합니다. 사용자가 값을 입력할 때마다 이벤트 핸들러 동작하고 상태(state)를 지속적으로 업데이트 되며 리렌더링 되고 있습니다. 그리고 상태(state)를 input value 속성에 할당함으로써 렌더링 된 상태(state)를 input 값으로 보여주고 있습니다.

export default function App() {
  const [value, setValue] = useState('');

  const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        value={value}
        onChange={(e) => {
          const { value } = e.target;
          setValue(value);
        }}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

📌 UnControlled Componenst(비제어 컴포넌트)

비제어 컴포넌트(Uncontrolled Component)는 React에서 상태(state)를 관리하지 않는 컴포넌트를 의미합니다. 이러한 컴포넌트는 React의 상태에 의존하지 않고, 일반적으로 ref를 사용하여 DOM 요소에 직접 접근합니다.

비제어 컴포넌트를 사용하기 위해서는 useRef를 사용하여 DOM에 직접 접근 합니다.
input 값을 사용하려면 이벤트 트리거가 발생했을 때 DOM에 접근하여 입력값을 참조할 수 있는데 이때 DOM에 저장된 value Attribute의 값을 가져옴으로 신뢰 가능한 단일 출처의 값을 알 수 있습니다.

export default function App() {
  const inputRef = useRef(null);

  const handleSubmit = (e:FormEvent<HTMLFormElement>) => {
    e.preventDefault();
  };

  return (
    <form onSubmit={handleSubmit}>
      <input ref={inputRef} />
      <button type="submit">Submit</button>
    </form>
  );
}

📌 제어 컴포넌트와 비제어 컴포넌트 비교

제어컴포넌트비제어 컴포넌트
데이터 관리주체ReactDOM
데이터 갱신 시점사용자가 값을 입력할때 마다 갱신특정 시점에서 DOM에서 Pull하여 갱신
리렌더링 여부값을 입력할 때 마다 발생값을 입력할 때는 발생하지 않는다

📌 제어 컴포넌트와 비제어 컴포넌트는 언제 사용할까❓

제어 컴포넌트를 사용하는 경우

  • 즉각적, 실시간으로 값에 대한 검증이나 피드백이 필요한 경우
  • 조건에 따른 Submit 버튼 활성화, 비활성화 구현
  • 실시간 유효성 검사 기능
  • 실시간으로 입력 형식을 적용 할 때
  • 일회성 정보를 검색
  • Submit 이벤트 발생 시 값 검증 할 때

비제어 컴포넌트를 사용하는 경우

  • 즉각적, 실시간 검증이 불필요하고 제출시에만 값이 필요한 경우
  • 불필요한 렌더링을 줄이기 위한 경우
  • Submit 이벤트 발생 시 값 검증 하는 경우

현재 리액트 공식 문서에서는 제어컴포넌트를 사용하는 것을 권장하고 있지만 각각 상황에 맞춰 쓰면 될 것 입니다.

마치며

NEXTSTEP TDD, 클린 코드 with React 3기를 진행하면서 기존에 알던 것들을 정리하는 시간을 가졌습니다.

제어 컴포넌트와 비제어 컴포넌트는 기존에 알고있던 내용이였지만 블로그 글을 발행하면 좋을거 같아서 복습 차원에서 작성하게 되었습니다. 그 과정에서 애매했던 부분을 확실하게 정립할 수 있어서 좋았던거 같습니다.

이처럼 기존에 알고있는 부분이라도 잘못된 부분이나 애매한 부분이 있는지에 대해 확실하게 짚고 넘어갈 수 있는 시간을 가져보려고 합니다.

참고

profile
열정적인 개발자

0개의 댓글