개발 공부 일지/React

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

dev-hpk 2024. 10. 4. 20:49

React에서는 사용자 입력을 처리하는 두 가지 주요 방식이 있습니다: 제어 컴포넌트와 비제어 컴포넌트 이 두 방식은 각기 다른 상황에서 유용하며, 각각의 장단점을 이해하는 것은 React 애플리케이션을 효과적으로 개발하는 데 중요한 요소입니다.

 

 

react 컴포넌트 - 커버 이미지

 

목차

1. 제어 컴포넌트란?

2. 비제어 컴포넌트란?

3. 제어 컴포넌트와 비제어 컴포넌트, 어떻게 사용할까?

4. 입력하기

추천글

위의 목차를 클릭하면 해당 글로 자동 이동 합니다.

 

1. 제어 컴포넌트 (Controlled Components)

제어 컴포넌트는 React state(상태)를 사용하여 컴포넌트의 값을 제어합니다. 즉, 컴포넌트의 입력 값은 React state(상태)에 의해 관리되며, 사용자의 입력이 있을 때마다 상태를 업데이트하여 UI를 갱신합니다.

import React, { useState } from 'react';

const ControlledInput = () => {
  const [value, setValue] = useState('');

  const handleChange = (e) => {
    setValue(e.target.value);
  };

  return (
    <div>
      <input type="text" value={value} onChange={handleChange} /> // input의 value 값을 React에서 지정
      <p>입력한 값: {value}</p>
    </div>
  );
};

export default ControlledInput;

 

 

장점

  • 단일 데이터 소스: 컴포넌트의 상태와 입력 값이 항상 일치하므로, 데이터 흐름이 명확합니다.
  • 유효성 검사 및 조작 용이: 입력 값에 대한 유효성 검사 및 조작을 쉽게 수행할 수 있습니다.

단점

  • 성능: 상태 변경 시마다 리렌더링이 발생하여 성능에 영향을 줄 수 있습니다.
  • 복잡성: 대규모 폼에서 상태 관리가 복잡해질 수 있습니다.

 

2. 비제어 컴포넌트 (Uncontrolled Components)

비제어 컴포넌트는 React state(상태)를 사용하지 않고 DOM 요소에 직접 접근하여 값을 처리합니다. 즉, 입력 값은 React 외부에서 관리되며, ref를 통해 접근할 수 있습니다. 이 경우 input에 value 속성을 설정하지 않습니다.

import React, { useRef } from 'react';

const UncontrolledInput = () => {
  const inputRef = useRef(null);

  const handleSubmit = (e) => {
    e.preventDefault();
    alert('입력한 값: ' + inputRef.current.value);
  };

  return (
    <div>
      <input type="text" ref={inputRef} /> // input의 value 값을 React에서 지정 X
      <p>입력한 값: {value}</p>
    </div>
  );
};

export default UncontrolledInput;

 

장점

  • 간단한 구현: 작은 폼(form)에서는 설정이 간단하고 빠르게 구현할 수 있습니다.
  • 성능: 리렌더링이 필요하지 않으므로 성능이 우수합니다.

단점

  • 데이터 흐름 관리의 복잡성: React 상태와 DOM 상태가 분리되어 있으므로, 데이터 흐름 관리가 복잡해질 수 있습니다.
  • 유효성 검사: 입력 값에 대한 유효성 검사를 직접적으로 처리하기 어려울 수 있습니다.

 

3. 제어 컴포넌트와 비제어 컴포넌트, 어떻게 사용할까?

제어 컴포넌트

사용자 입력을 정밀하게 제어하고, 상태를 기반으로 UI를 업데이트해야 할 때 유용합니다. 예를 들어, 입력 값의 유효성을 검사하거나 동적으로 UI를 변경해야 할 경우 사용합니다.

비제어 컴포넌트

간단한 폼이나 상태 관리가 필요 없는 경우 유용합니다. 입력 값에 대한 단순한 접근이 필요할 때 적합합니다.
파일을 다루는 입력의 경우 반드시 비제어 컴포넌트를 사용해야 합니다.

예시

import { useState } from 'react';

function App() {
  const [file, setFile] = useState();
  return (
    <input
      type="file"
      value={file}
      onChange={(e) => setFile(e.target.files[0])}
    />
  );
}

export default App;


파일을 제어 컴포넌트로 다루니 아래처럼 에러가 발생했습니다.

 

올바른 사용법

import {useState, useRef} from 'react';

function APP() {
  const [file, setFile] = useState();
  const fileRef = useRef();
  
  // 선택한 파일을 state(상태)에 지정하는 함수
  const handleChange = (e) => {
    const nextValue = e.target.files[0];
	setFile(nextValue);
  };
  
  // 선택한 파일을 지우는 함수
  const handleClear = () => {
    if (!fileRef.current) return; // 선택된 파일이 없는 경우
    fileRef.current.value = null;
    setValue(null);
  };
  

  return (
    <div>
      <input type="file" ref={fileRef} onChange={handleChange} />
 	  <button onClick={handleClear}>지우기</button>
    </div>
  );
}
export default App;

 

 

 

리액트의 제어 컴포넌트비제어 컴포넌트는 각각의 필요에 따라 선택하여 사용할 수 있는 강력한 도구입니다. 상황에 맞게 적절한 방식을 선택하여 개발하면 더 효율적이고 관리하기 쉬운 애플리케이션을 만들 수 있습니다. 

 

만약 제어 컴포넌트와 비제어 컴포넌트를 모두 사용할 수 있는 상황이라면 제어 컴포넌트 사용을 추천드립니다.

 

 

추천글

2024.10.01 - [개발 공부 일지/React] - [React] 리액트 useEffect란?

 

[React] 리액트 useEffect란?

리액트에서 useEffect는 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 Hook입니다. React 컴포넌트가 렌더링 된 후 특정 코드를 실행하고, 컴포넌트가 언마운트되거나 상태가 변

dev-hpk.tistory.com

2024.09.28 - [개발 공부 일지/React] - [React] 리액트 컴포넌트란?

 

[React] 리액트 컴포넌트란?

React는 모듈화 된 사용자 인터페이스를 구축하기 위한 라이브러리로, 그 핵심은 컴포넌트입니다. 컴포넌트는 화면의 일부분을 구성하고, 재사용 가능하며 독립적인 단위를 제공합니다. 이번 포

dev-hpk.tistory.com

 

'개발 공부 일지 > React' 카테고리의 다른 글

[React] 리액트 Context  (0) 2024.10.07
[React] 리액트 useCallback란?  (1) 2024.10.06
[React] 리액트 useEffect란?  (6) 2024.10.01
[React] 리액트 State와 useState  (3) 2024.09.30
[React] 리액트 Props란?  (1) 2024.09.28