[React] Controlled/Uncontrolled 컴포넌트

OROSY·2021년 10월 3일
6

React

목록 보기
25/27
post-thumbnail

🎮 Contorlled/Uncontrolled Component

엘리먼트 중에는 상태를 가지고 있는 것들이 있습니다.

  • input
  • select
  • textarea
  • ...

등이 이 예에 속합니다. 그래서 엘리먼트의 '상태'를 누가 관리하느냐에 따라 ContorlledUncontrolled Component로 나뉩니다.

엘리먼트를 가지고 있는 컴포넌트가 관리한다면, Contorlled Component, 엘리먼트의 상태를 관리하지 않고 엘리먼트의 참조만 컴포넌트가 소유한다면, Uncontorlled Component라고 할 수 있습니다.

이에 대한 자세한 사항은 리액트 공식문서를 확인해보시면 되니 참고 부탁드리겠습니다.

🤓 Controlled Component

우리는 React state를 “신뢰 가능한 단일 출처 (single source of truth)“로 만들어 두 요소를 결합할 수 있습니다.

그러면 폼을 렌더링하는 React 컴포넌트는 폼에 발생하는 사용자 입력값을 제어합니다. 이러한 방식으로 React에 의해 값이 제어되는 입력 폼 엘리먼트를 제어 컴포넌트 (controlled component)라고 합니다.

input 엘리먼트로 아래와 같이 예를 들어보도록 하겠습니다.

import React, { Component } from "react";

export class ControlledComponent extends Component {
  constructor() {
    super();
    this.state = {
      value: "",
    };
  }

  render() {
    const { value } = this.state;
    return (
      <div>
        <input value={value} onChange={this.change} />
        <button onClick={this.click}>전송</button>
      </div>
    );
  }

  change = (e) => {
    console.log(e.target.value);
    // render가 다시 일어남
    this.setState({ value: e.target.value });
  };

  click = () => {
    console.log(this.state.value);
  };
}

export default ControlledComponent;

🤪 Uncontorlled Component

대부분 경우에 폼을 구현하는데 제어 컴포넌트를 사용하는 것이 좋습니다. 제어 컴포넌트에서 폼 데이터는 React 컴포넌트에서 다루어집니다. 대안인 비제어 컴포넌트DOM 자체에서 폼 데이터가 다루어집니다.

모든 state 업데이트에 대한 이벤트 핸들러를 작성하는 대신 비제어 컴포넌트를 만들려면 ref를 사용하여 DOM에서 폼 값을 가져올 수 있습니다.

import React, { Component } from "react";

export class UncontrolledComponent extends Component {
  inputRef = React.createRef();

  render() {
    console.log("initial render", this.inputRef);
    return (
      <div>
        <input ref={this.inputRef} />
        <button onClick={this.click}>전송</button>
      </div>
    );
  }

  componentDidMount() {
    console.log("componentDidMount", this.inputRef);
  }

  click = () => {
    // input 엘리먼트의 현재 상태 값(value)을 꺼내서 전송한다.
    // const input = document.querySelector("#my-input");
    // console.log(input.value);
    // 위의 코드는 실제 DOM을 업데이트하므로 지양해야하는 방법!

    console.log(this.inputRef.current.value);
  };
}

export default UncontrolledComponent;

예를 들어, 로그인 유효성 검사 로직이 매번 state 값이 변화함에 따라 화면에 그려내야하는 경우라면 제어 컴포넌트가 쉬운 방식일 것입니다.

그리고 예를 들어 마우스로 비제어 컴포넌트에 올렸을 때, focus 되게 하고 싶다면, 이벤트에 맞춰서 실제 엘리먼트에 focus를 주어야하므로 ref로 실제 DOM을 참조하여 액션을 취하는 것이 더 좋은 방법이 될 것입니다.

이렇게 각자의 경우에 필요한 때에 적절한 방법을 취하는 것이 좋습니다. 저도 이렇게 각 상황에 따라 맞는 React 문법을 사용할 수 있도록 해야할 것 같습니다💪

profile
Life is a matter of a direction not a speed.

0개의 댓글