본문 바로가기
Tech/React

Controlled Components, Uncontrolled components

by egas 2021. 8. 3.

사전 지식

우선 두 가지 개념을 알아보기 전에, 기본 개념을 알아보자.

 

HTML에서 <input>, <select>, <textarea> 같은 Form element는 사용자 입력에 기반해서 자신의 상태를 유지하거나 갱신한다. 즉, HTML 태그 자체적으로 상태를 갖는다.

 

Input event

Input event가 발생하면, <input>, <textarea>, <select>의 value가 변한다.

https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event

 

HTMLElement: input event - Web APIs | MDN

The input event fires when the value of an

,

 

Change event

Change event는 <input>, <textarea>, <select>의 value가 변한 후, 아래 세 가지 경우중 하나일 때 발생한다.

 

 

https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event

 

HTMLElement: change event - Web APIs | MDN

The change event is fired for

,

 

TL;DR

React의 Controlled Components와 Uncontrolled components의 차이는 push(Controlled Components)와 pull(Uncontrolled components) 차이이다.

 

Controlled Components 가 생겨난 이유

 

React는 내부의 상태(state)에 대해 'Single Source of Truth(신뢰 가능한 단일 소스)' 설계 철학을 가지고 있다. Single Source of Truth에 대해서는 아래 링크를 참고하자.

https://egas.tistory.com/89

 

Single Source of Truth

정보의 중복, 비정합성 등의 문제를 해결하고자 나온 이론. 아래 예시를 보자. 홈페이지를 만든다. About 페이지에서 네비게이션 기능이 필요해서 만들었다. Category 페이지에 네비게이션 기능이

egas.tistory.com

 

즉, React는 같은 state가 여러 곳에 존재하지 않고, 자식에서 부모의 state가 필요할 경우 props로 받아서 사용하길 지향한다. 하지만, HTML element 중 자체적으로 특정 data를 가지는 엘리먼트들이 있다. <Form>과 관련된 태그들이며, 위에서 소개한 <input>, <textarea>, <select>의 경우이다.

 

이 세 가지 태그에 대해, 사용자가 정보를 입력할 경우, 해당 정보를 HTML element가 직접 가지고 있다. 이때, 자바스크립트와 HTML element 두 곳에서 입력에 대한 상태를 독립적으로 소유하고 있기 때문에, Single Source of Truth에 위배된다.

 

React는 이를 해결하고자 Controlled Conponents를 만들었다.

 

Uncontrolled components

  • Uncontrolled components: Pull the value
class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

DOM과 유저가 상호작용한 정보가 담겨있다. React Component가 DOM이 관리하는 정보를 알기 위해서는 실제 DOM에 접근해야 한다. React는 ref를 통해서 접근한다.

 

ref prop에 넘겨진 콜백함수는 componentDidMount() 또는 componentDidUpdate() 직전에 호출된다. 따라서, componentDidMount()가 실행되는 시점에 DOM에서 ref를 통해서 받아온 정보에 대한 참조를 저장할 수 있다. 최종적으로 handleSubmit 메서드가 버튼 클릭으로 실행될 때 해당 참조에 대한 정보를 컴포넌트 내부에 저장된다.

 

즉, 우리는 React Component가 HTML element로부터 정보를 PULL 한다고 볼 수 있다.

 

이것은 컴포넌트 내부에서 정보를 관리하는 것이 아니기 때문에, 실시간 작업 처리에는 적합하지 않다.

 

Controlled components

  • Controlled components: Push the value
class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

React에서 상태관리는 오직 State로만 관리한다. Single Source of Truth에 의거하여 React에서 사용자 입력의 상태를 제어하는 것을 Controlled Component라 한다.

 

즉, 현재 HTML element에 들어온 정보를 state로 상태 관리하고, 변경된 state를 기반으로 HTML 엘리먼트의 value를 변경시키는 방식이다.

 

DOM의 정보를 컴포넌트 내부에 state로 저장하고 state를 기반으로 HTML 엘리먼트를 다시 re-rendering 시키므로 이 방법이 React 철학에 Uncontrolled Component 보다 가깝다고 할 수 있다.

 

사용자 입력을 기반으로 state를 변경 한 후, state를 input 태그의 value로 설정하고 있기 때문에, 우리는 React Component가 HTML element에 PUSH 한다고 볼 수 있다.

 

우리는 React Component 내에서 상태를 관리하여, 입력 태그들과의 동기화를 이루기 때문에 실시간으로 작업을 처리할 수 있다.

 

참고

https://reactjs.org/docs/forms.html#controlled-components

 

Forms – React

A JavaScript library for building user interfaces

reactjs.org

https://reactjs.org/docs/uncontrolled-components.html

 

Uncontrolled Components – React

A JavaScript library for building user interfaces

reactjs.org

 

728x90

'Tech > React' 카테고리의 다른 글

SyntheticEvent and throttle  (0) 2021.08.07
ReactElement.js  (2) 2021.08.04
React Element vs Component  (0) 2021.08.01
useEffect 정리  (0) 2021.07.22
[Typescript] CRA에서 http-proxy-middleware 사용법  (0) 2021.07.14

댓글