본문 바로가기

REACT

[ React ] Element, Component, Instance 개념정리 ( with - React가 DOM Tree를 파악하는 방법 )

728x90
반응형

영상을 보고 정리한 글입니다! ( https://www.youtube.com/watch?v=QSJUTS9PScY )

 

 

 

 

기존 UI model(OOP)의 문제점

아래 코드를 참고해 설명하자면, button의 속성(isSubmitted, buttonText)에 따라
버튼이 화면에 그려지거나( this.button.render() ) 제거( this.button.destroy() )되는 등의 관리가 필요하다.

 

 

각 컴포넌트가 많아지면, 버튼 같은 instance도 많아지고,

instance를 조작하는 코드를 일일히 조작해주어야 하는 부분도 많아져 관리할 코드가 늘어나고,

이렇게 되면 부모 컴포넌트와 자식 컴포넌트의 분리가 어려워진다.

 

class Form extends TraditionalObjectOrientedView {
  render() {
    // Read some data passed to the view
    const { isSubmitted, buttonText } = this.attrs;

    if (!isSubmitted && !this.button) {
      // Form is not yet submitted. Create the button!
      this.button = new Button({
        children: buttonText,
        color: 'blue'
      });
      this.el.appendChild(this.button.el);
    }

    if (this.button) {
      // The button is visible. Update its text!
      this.button.attrs.children = buttonText;
      this.button.render();
    }

    if (isSubmitted && this.button) {
      // Form was submitted. Destroy the button!
      this.el.removeChild(this.button.el);
      this.button.destroy();
    }

    if (isSubmitted && !this.message) {
      // Form was submitted. Show the success message!
      this.message = new Message({ text: 'Success!' });
      this.el.appendChild(this.message.el);
    }
  }
}

 

 

위의 문제때문에 리액트가 활용한 개념 

1. Elements는 화면에 그려질 DOM tree에 대한 정보를 가지고 있는것이다.

2. Elements는 인스턴스가 아니다.

3. Elements가 생성되면 아래 두가지 프로퍼티를 가진다.

     1️⃣   type : string | ReactClass,
             - string이 할당되는 경우 : html태그인 경우 = DOM Elements일때

             - ReactClass가 할당되는 경우 : Component Elements일때

 

     2️⃣   props : object
             - Dom Elements일 경우 : className, chlidren 같은 html의 attribute(속성)

             - Component Elements일 경우 : Component Elements에 어떤 정보를 전달해야 렌더링 될지 하는 속성

 

// type: string  |  React DOM elements 
{
    type: 'button',
    props: {
       className: 'button button-blue',
       children: {
            type: 'b',
            props: {
               children: 'OK!'
            }
       }
    }
}


<button class='button button-blue'>
  <b>
    OK!
  </b>
</button>

 

// type: ReactClass | React Component elements
{
    type: Button,
    props: {
       color: 'blue',
       children: 'OK!'
    }
}

 

 

한계를 극복하게 한것

다른 Elements를 으로 children가질 수 있게 구조가 되어 있음  => tree구조가 될 수 있음

React에서 작성한 React compoenent와 실제 DOM Elements가 같은 위계에서 관리가 될 수 있다.

= 기존의 DOM node와 React component를 mixed,nested한 구조가 가능해짐

 

// React DOM, Component elements decoupled
{
    type: Button,
    props: {
       color: 'blue',
       children: 'OK!'
    }
}
const DeleteAccount = () => (
  {
    type: 'div',
    props: {
    children: [
      {
          type: 'p',
          props: {
              children: 'Are you sure?'
          }
      }, 
      {
          type: DangerButton,
          props: {
              children: 'Yep'
          }
      },
      {
          type: Button,
          props: {
              color: 'blue',
              children: 'Cancel'
          }
      }
    ]
  }
);


const DeleteAccount = () => (
  <div>
    <p>Are you sure?</p>
    <DangerButton>Yep</DangerButton>
    <Button color='blue'>Cancel</Button>
  </div>
);

 

 

React가 DOM Tree를 파악하는 방법.

함수형 컴포넌트인 경우에는 props를 받아 Elements를 리턴

클래스형 컴포넌트의 경우에는 render라는 메서드에서 Elements를 리턴

 

  1. type: Component Elements 인 Elements를 만난다.

  2. 해당 component Elements에 Elements를 리턴 받는다.

  3. 리턴받은 Elements의 type이 Dom Elements(html태그)인 경우일때 까지 1,2번을 반복한다.

 

이렇게 되면 react는 모든 dom tree를 완벽하게 알게되고,

리액트는 렌더링과 제거되는 부분을 적절하게 알고 따로 진행한다.

그리고 우리 작성한 Component Elements에서는DOM tree에 전달할 정보만 작성해주면 된다.

 

 

실제 Dom의 구조를 활용하는게 아니라 React Elements를 활용해서 

나머지 로직들은 다른곳에서 제어하고, 필요한 정보만 독립적으로 UI로 관리 할 수 있도록 가능하게 한다.

 

그래서 기존의 UI모델링을 분리해서 간단하게 구현 할 수있게 된다.

 

결국

Elements는 Dom tree에게 전달할 정보를 가지고 있는 자바스크립트 객체다.

그 객체가 Elements tree를 이루게 되는데 리액트가 이 Elements tree를 알고있고,

React가 언제 화면에 그려지거나(render) 제거(destroy)되는 부분들을 알고 알아서 수행하게 되는것이다.

 

 

 

Top-Down Reconciliation

위에서 정리했던 아래의 이 과정을  Top-Down Reconciliation 이라고 한다.

  1. type: Component Elements 인 Elements를 만난다.
  2. 해당 component Elements에 Elements를 리턴 받는다.
 3. 리턴받은 Elements의 type이 Dom Elements(html태그)인 경우일때 까지 1,2번을 반복한다.

리액트가 렌더링이 일어날때, Reconciliation이 실행되고,

Reconciliation이 끝나면 Elements tree를 알게된다.

이 트리를 renderer(react dom)에게 전달하고, renderer가 최소한의 변화를 실제 Dom node에 업데이트 적용한다.

 

점진적으로 변화가 일어나기 때문에 쉽게 최적화가 가능하다.

props가 고정적이면 변경되는 계산이 더 빨라진다.

 

 

마지막으로,

Instance란?

Instance는 클래스로 선언된 컴포넌트에서만 갖는다.

우리가 클래스를 호출해서 직접 Instance를 만드는게 아니라
리액트가 class componet의 Instance를 만들어준다.(클래스 컴포넌트의 this 값)

+ ) 함수형 컴포넌트는 Instance를 갖지 않는다!

 

 

 

결론

Element, Component, Instance 

1. Elements는 화면에 그려질 DOM tree에 대한 정보를 가지고 있는것

2. Component는 데이터를 입력받아 DOM Node를 출력하는, 리액트로 만들어진 앱을 이루는 최소한의 단위

3. Instance 클래스로 선언된 Component에서만 갖는다.

 


✔️ 참고

 

https://www.youtube.com/watch?v=QSJUTS9PScY 

https://hkc7180.medium.com/react-components-elements-and-instances-%EB%B2%88%EC%97%AD%EA%B8%80-b5744930846b

https://ko.reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html

 

 

 

 

728x90
반응형