[fastcampus] Ch.6-2 Controlled/Uncontrolled Component

productuidev·2022년 3월 11일
0

React Study

목록 보기
13/52
post-thumbnail
post-custom-banner

패스트캠퍼스 한 번에 끝내는 프론트엔드 개발(Online) 강의 정리


2. Controlled/Uncontrolled Component

상태를 가지고 있는 엘리먼트

자체적으로 특정 data를 가진 엘리먼트 ---> form
input select textarea ---> 컴포넌트 상태로 관리하기

사용자가 DOM에서 어떤 정보를 입력하거나 선택할 경우,
해당 정보를 HTML 엘리먼트가 직접 보관 > 내부 상태(state)를
신뢰 가능한 단일 소스(Single Source of Truth) 설계 원칙에 위배하므로
이를 해결하기 위해 React에서 Controlled Component 개념이 나온 것임

엘리먼트의 '상태'를 누가 관리하느냐

  • Controlled : 엘리먼트를 가지고 있는 컴포넌트가 관리
  • Uncontrolled : 엘리먼트의 상태를 관리하지 않고, 엘리먼트의 참조만 컴포넌트가 소유 (Reference API 사용)

대부분 경우에 폼을 구현하는데 제어 컴포넌트를 사용하는 것이 좋습니다.
제어 컴포넌트에서 폼 데이터는 React 컴포넌트에서 다루어집니다.
대안인 비제어 컴포넌트는 DOM 자체에서 폼 데이터가 다루어집니다.
모든 state 업데이트에 대한 이벤트 핸들러를 작성하는 대신
비제어 컴포넌트를 만들려면 ref를 사용하여 DOM에서 폼 값을 가져올 수 있습니다.
https://ko.reactjs.org/docs/uncontrolled-components.html

Controlled Component

  • 데이터를 PUSH하는 방식 : 현재 HTML 엘리먼트에 들어온 정보를 prop으로 state 변경 ---> 변경된 state 기반으로 엘리먼트의 value를 변경시킴
  • DOM 정보를 컴포넌트 내부에 state로 저장하고 state 기반으로
    HTML 엘리먼트를 다시 렌더링시킴

src/components/ControlledComponent.jsx

import React from 'react';

class ControlledComponent extends React.Component {
  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);
    this.setState( { value: e.target.value} );
  };

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

}

export default ControlledComponent;

src/App.js

import ControlledComponent from "./components/ControlledComponent";

function App() {
  return(
    <div className="App">
      <p>
        <ControlledComponent />
      </p>
    </div>
  );
}


출처 - https://velog.io/@gtah2yk/Controlled-and-uncontrolled-form-inputs-in-React-dont-have-to-be-complicated-%EC%9A%94%EC%95%BD

Uncontrolled Component

  • 데이터를 PULL하는 방식 : 전통적인 HTML form input과 유사
  • DOM에 의해서 자체적으로 유저가 상호작용한 정보가 담김
  • input 태그 내부에 부여된 ref prop에 넘겨진 정보에 대한 참조가 저장됨
  • 데이터에 액세스해야 할 때마다 ref를 사용

src/components/UncontrolledComponent.jsx

import React from 'react';

class UncontrolledComponent extends React.Component {
  // Reference API (참조로 가지고 있다가 사용)
  inputRef = React.createRef();

  render() {

    console.log("initial render", this.inputRef);

    return (
      <div>
        <input ref={this.inputRef} /> // Ref API에 잠시 보관
        <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); // realDOM (리액트가 지양하는 방식..)

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

  };

}

export default UncontrolledComponent;

src/App.js

import ControlledComponent from "./components/ControlledComponent";
import UncontrolledComponent from "./components/UncontrolledComponent";

function App() {
  return(
    <div className="App">
      <p>
        <ControlledComponent />
        <UncontrolledComponent />
      </p>
    </div>
  );
}

참고 자료

https://soldonii.tistory.com/145
https://so-so.dev/react/form-handling/
https://velog.io/@aksel26/Controlled-UnControlled-Component
https://gaemi606.tistory.com/entry/React-Uncontrolled-Components

profile
필요한 내용을 공부하고 저장합니다.
post-custom-banner

0개의 댓글