본문 바로가기
FE - Tools/React

[React] 제어 컴포넌트와 비제어 컴포넌트를 적절하게 사용하는 법

by thedev 2023. 3. 12.

 

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

 


 

 제어 컴포넌트비제어 컴포넌트란, React에서 form 태그 엘리먼트를 다루는 방법이다. form 태그 엘리먼트는 자체적으로 데이터를 가진다는 특정이 있다. 이 특성 때문에 form 태그 엘리먼트를 다루는 방법이 두 가지로 나뉜다. form 태그 엘리먼트 중 가장 자주 사용되는 input 태그를 예로 들어 제어 컴포넌트와 비제어 컴포넌트를 설명해보려 한다.

 

 React에서는 input의 value 값을 다룰 때  state를 사용하거나 ref를 사용한다. state를 사용하는 것을 제어 컴포넌트, ref를 사용하는 것을 비제어 컴포넌트라고 한다.

 

 

# 제어 컴포넌트

 

import React, { useState } from 'react';

export default function App() {
   const [email, setEmail] = useState();
   
   const handleChange = (event) => {
      setPassword(event.target.value);
   };
  
   return (
      <div>
         <input
            type="text"
            value={email}
            onChange={handleChange}
         />
      </div>
   );
}

 

 useState로 input의 value를 저장하고, input의 입력값이 변경될 때마다 useState는 값을 업데이트한다. 값이 바뀔 때마다 리렌더링이 일어나기 때문에 화면에 보이는 값과 컴포넌트가 관리하는 상태의 값이 일치한다.

 

 

# 비제어 컴포넌트

 

 비제어 컴포넌트란 input의 데이터를 DOM 자체에 저장하는 것으로, ref를 이용하여 직접 input의 데이터에 접근하는 것이다. 이 모습은 바닐라 자바스크립트와 상당히 비슷하다. 우선 바닐라 자바스크립트를 살펴보자.

 

<!-- 바닐라 자바스크립트 -->

<body>
 
    <script>
      const inputChange = () => {
        const test = document.getElementById("test");
        document.getElementById("result").innerText = test.value;
      };
    </script>
    
    <input id="test" onchange="inputChange()" />
    <h1 id="result"></h1>
    
</body>

 

 바닐라 자바스크립트에서는 getElementbyId를 이용해 직접 값에 접근한다. 이와 마찬가지로 React에서는 DOM에 접근하여 input 값에 접근하고 싶다면 ref를 이용한다.

 

import React, { useRef } from 'react';

export default function App() {
   const inputRef = useRef();
   const handleClick = () => {
      console.log(inputRef.current.value);
   }
   
   return (
      <div>
         <input ref={inputRef} />
         <button onClick={handleClick}>확인</button>
      </div>
   );
}

 

 이 방법을 이용하면 값이 실시간으로 동기화되지 않는다. 제어 컴포넌트는 사용자가 입력을 할 때마다 리렌더링을 시키고 값을 동기화하는 반면 비제어 컴포넌트는 사용자가 직접 동작을 하기 전까지는 리렌더링을 하지 않고 값을 동기화하지도 않는다.

 

 제어 컴포넌트를 사용하면 값을 실시간으로 확인할 수 있지만 계속해서 리렌더링이 되기 때문에, 불필요한 리렌더링을 줄이고 제출 시에만 값을 사용하고자 한다면 비제어 컴포넌트를 사용하는 것이 좋다.

 


 

input 다룰 때 항상 state만 써봤는데 ref를 쓰는 방법이 있었구나😮 로그인 기능 구현할 때 글자 하나하나 다 리렌더 되는 게 비효율적이라 바꾸고 싶었는데 ref를 써봐야겠다

 

 

참고 자료

[10분 테코톡] 후이의 제어 컴포넌트 vs 비제어 컴포넌트 https://youtu.be/LD1LyvCCbCg

https://handhand.tistory.com/261