[React 공식문서 공부하기] 제어 컴포넌트 vs 비제어 컴포넌트

FE_Sujin·2024년 6월 16일
0

React

목록 보기
8/8
post-thumbnail

제어 컴포넌트 (Controlled Component)

React에 의해 값이 제어되는 입력 폼 엘리먼트

HTML에서 <input>, <textarea>, <select>와 같은 폼 엘리먼트는 일반적으로 사용자의 입력을 기반으로 자신의 state를 관리하고 업데이트한다.

React에서는 변경할 수 있는 state가 일반적으로 컴포넌트의 state 속성에 유지되며 setState() 함수에 의해 업데이트 된다.

그러면 폼을 렌더링하는 React 컴포넌트는 폼에 발생하는 사용자 입력값을 제어한다.

이러한 방식으로 React에 의해 값이 제어되는 입력 폼 엘리먼트"제어 컴포넌트 (controlled component)" 라고 한다.

const Form = () => {
  const [input, setInput] = useState('');
  const onChange = (e) => setInput(e.target.value);

  return (
  	<div>
      <input onChange={onChange} />
    </div>
  )
}

위 예시처럼, 사용자의 입력을 받는 태그에 event 객체를 이용해 setState()로 값을 저장하는 방식과 같이, React에 의해 값을 제어되는 컴포넌트를 제어 컴포넌트이다.

제어 컴포넌트는 사용자가 입력한 값과 저장되는 값이 실시간으로 동기화된다.

제어 컴포넌트를 사용하면,

사용자가 입력할 때마다 보여지는 값이 업데이트 되고, 이 입력값은 항상 React State에 의해 결정된다.

다른 UI 엘리먼트에 입력값을 전달하거나 다른 이벤트 핸들러에서 값을 재설정할 수 있다.


비제어 컴포넌트 (Unctrolled Component)

setState()가 아닌 ref를 사용하여 DOM에서 폼 값을 가져오는 컴포넌트

비제어 컴포넌트는 DOM 자체에서 폼 데이터가 다루어진다.

모든 state 업데이트에 대한 이벤트 핸들러를 작성하는 제어 컴포넌트와 달리,

비제어 컴포넌트는 ref를 사용하여 DOM에서 폼 값을 가져올 수 있다.

const NameForm = () => {
  const inputRef = useRef();
  
  const handleSubmit = () => console.log(inputRef.current.value);

  return (
  	<form onSubmit={handleSubmit}>
      <label>
        Name:
        <input type='text' ref={inputRef} />
      </label>
    </form>
  )
}

따라서 제어 컴포넌트의 경우 사용자가 입력을 하는 액션을 취할때마다 리렌더링을 발생시키는 반면,

비제어 컴포넌트는 ref를 사용하기 때문에 사용자가 직접 트리거 하기 전까지는 리렌더링을 발생시키지도 않고 값을 동기화 시키지도 않는다.


제어 컴포넌트 vs. 비제어 컴포넌트

제어 컴포넌트

  • 값을 항상 최신값으로 유지한다. (setState()를 이용해서) 새로운 값을 입력할 때마다 새롭게 값을 업데이트해준다.

  • 데이터와 UI에서 입력한 값이 항상 동기화된다.


비제어 컴포넌트

  • 필드에서 값을 트리거 해야 값을 얻을 수 있다. (ex. '전송' 버튼을 눌러 폼 제출)

  • '전송' 버튼을 누르는 등 트리거 하기 전까지는 값이 변경되지 않는다.


제어 컴포넌트, 비제어 컴포넌트별 가능한 기능들

기능제어 컴포넌트비제어 컴포넌트
일회성 정보 검색 ( 예: 제출 )OO
제출 시 값 검증OO
실시간으로 필드값의 유효성 검사OX
조건부로 제출 버튼 비활성화 ( disabled )OX
실시간으로 입력 형식 적용하기 ( 숫자만 가능하게 등 )OX
동적 입력OX

⭐ 정리!

  • 즉각적으로, 실시간으로 값에 대한 피드백이 필요하다 > 제어 컴포넌트 사용
  • 즉각적인 피드백이 불필요하고 제출시에만 값이 필요하다, 불필요한 렌더링과 값 동기화가 싫다 > 비제어 컴포넌트 사용

제어 컴포넌트는 언제 사용할까?

  • 유효성 검사 필요할 때

  • 유효한 데이터 없는 경우 전송 버튼의 상태를 disabled 해야 할 때

  • 신용 카드 같은 특정 입력 방식 적용할 때


제어 컴포넌트 사용할 때의 문제점

제어 컴포넌트는 UI에서 입력된 데이터 상태와 React의 state 데이터 상태가 항상 일치하는 것이기 때문에,

사용자가 입력할 때마다 데이터 동기화를 위해 불필요한 리렌더링이 발생하고, 불필요한 값까지 업데이트 된다.

ㅇ
아
안
안ㄴ
안녀
안녕
안녕!

이러한 불필요한 리렌더링, 값 업데이트를 막기 위해서는 throttle & debounce를 사용할 수 있다.

  • throttle : 마지막 함수 호출 후 일정 시간이 지나기 전에 해당 함수가 다시 호출되지 않도록 설정해주는 것
  • debounce : 연이어 호출되는 함수 중 마지막 또는 제일 첫 함수만 호출되도록 설정해주는 것

만약 form 컴포넌트에서 값이 트리거된 이후에만 값이 업데이트 되어도 문제가 없다면,

ref를 사용하는 비제어 컴포넌트를 사용하는 게 불필요한 리렌더링 방지하는 데 도움이 될 수 있다.

이러한 비제어 컴포넌트를 사용해 렌더링을 최적화하는 라이브러리React-Hook-Form 이다.


참고

profile
안녕하세요 :)

0개의 댓글

관련 채용 정보