프론트엔드 개발/React

React) 제어컴포넌트 비제어컴포넌트

Ella Seon 2023. 9. 13. 21:30

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://velog.io/@yukyung/React-%EC%A0%9C%EC%96%B4-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%99%80-%EB%B9%84%EC%A0%9C%EC%96%B4-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0

 

React: 제어 컴포넌트와 비제어 컴포넌트의 차이점

👀 제어 컴포넌트와 비제어 컴포넌트의 차이점, 활용 방법에 대해 알아봅시다

velog.io

https://dkrnfls.tistory.com/248

 

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

react에서 제어 컴포넌트, 비제어 컴포넌트를 고려하여 form을 다루어야 하는 경우가 있었다. 제어 컴포넌트, 비제어 컴포넌트에 대한 개념이 없었고 이전에 formik을 다루었었던 경험이 있어서 습

dkrnfls.tistory.com

https://www.youtube.com/watch?v=PBgQKK6nelo