ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React 딥다이브
    프론트엔드 2025. 10. 15. 23:35

    🧐 클래스 컴포넌트

      •  클래스 컴포넌트에 대해 알아보자
    import React, { Component } from "react";
    
    class Counter extends Component {
      // ✅ state: 컴포넌트 내부 데이터
      state = { count: 0 };
    
      // ✅ 이벤트 핸들러
      handleClick = () => {
        this.setState({ count: this.state.count + 1 });
      };
    
      // ✅ render(): UI를 반환
      render() {
        return (
          <div>
            <p>Count: {this.state.count}</p>
            <button onClick={this.handleClick}>+</button>
          </div>
        );
      }
    }
    
    export default Counter;
    • 위 코드를 보면 클래스형 컴포넌트는 React.Component를 상속받아 사용한다는 점이 가장 눈에 띈다. 
    • 그 다음으로 render() 함수가 눈에 띈다. 클래스형 컴포넌트는 보니 클래스를 만들고 만든 클래스를 render 함수를 호출하는 구조인거 같다. 
    • 근데 보통 클래스는 인스턴스화를 통해 사용하는 걸로 알고 있다. 클래스형은 컴포넌트는 어떻게 인스턴스화를 하는걸까?? 
    🤔 내부 인스턴스화 
    React가 위 class 컴포넌트를 렌더링 하려고 하면, Fiber가 컴포넌트의 타입을 'ClassComponent'로 인식한다. 
    그 다음 beginWork()가 수행되고 다음에 인스턴스화가 된다고 한다. 

    class Hello extends React.Component {
      render() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    }
    
    export default Hello
    만약 다음과 같은 코드가 있다고 가정하면, React Fiber는 stateNode를 통해 new Component가 저장된다. 
    이후 인스턴스의 render 메서드를 호출해 가상DOM을 얻는다. 
    즉 render 메서드가 호출되면, Hello에 대한 Fiber가 생성된다. 그 다음 beginWork()가 호출된 후 인스턴스화가 발생한다. 

    🤔 근데 왜 리액트 내부에서 인스턴스를 할까 유저가 하면 안되는걸까
    - 이유는 인스턴스를 활용해 지속성을 보장했다고 한다. 참조하고 있으면 데이터가 가비지 컬렉터가 수거해가지 않기 때문이다. 
    React가 클래스형 컴포넌트를 인스턴스화하는 이유는, 생성된 인스턴스를 Fiber 트리가 stateNode로 참조함으로써 객체의 지속성(persistence) 을 유지하고, 이를 통해 컴포넌트의 상태(state) 와 생명주기(lifecycle) 를안정적으로 관리하기 위함이다

     

    클래스 컴포넌트 생명주기

    • 클래스형 컴포넌트에서 생명주기 메서드는 참 많이 언급된다. 
    • 근데 그 이유를 대강 알아차렸다. 리액트가 인스턴스의 지속성을 보장하기 때문에 라는 생각이 들었다. 
    • 그래서 어떤 렌더링이 일어나도 항상 같은 객체를 가르키게 되어 생명주기 메서드로 이를 관리하기 위해 만들었다는 생각이 들었다. 

    • 생명주기 메서드는 크게 3가지가 있다. 
    • Mount, Update, Unmount가 있다

    Mount

    • 컴포넌트가 생성되는 시점 
    • componentDidMount

    Update

    • 이미 생성된 컴포넌트의 내용이 변경되는 시점
    • componentDidUpdate

    Unmount

    • 컴포넌트가 더이상 존재하지 않는 시점
    • componentWillUnmount
    차례대로 살펴보자
    Mount
    - React가 인스턴스를 생성하고, constructor -> render 순으로 호출한 후, DOM에 실제 요소를 붙이면 componentDidMount()가 호출 된다. 

    Update
    - props가 바뀌거나 setState또는 forceUpdate가 호출되면, 동일한 인스턴스 유지한 후 render를 실행하고, DOM을 갱신 한 후 componentDidUpdate가 호출된다

    Unmount
    - React가 컴포넌트에서 트리를 제거하면, 실제 DOM에서 제거되지 전에 componentWilUnmount를 호출한다. 

    FiberNode(stateNode)   
    │   ├─ Mount → constructor() → render() → componentDidMount()
    │   ├─ Update → setState() → render() → componentDidUpdate()   
    │   └─ Unmount → componentWillUnmount() → 참조 해제 → GC 수거

    클래스 컴포넌트의 한계

    • 근데 생각해보자 리액트 파이버는 렌더 단계에서 비동기 처리로 하는데 클래스형 컴포넌트의 경우 트러블이 생길 수 있다. 
    • 리액트 공식문서를 참고했다. 렌더 단계의 라이프사이클 메서드들이 비동기 처리를 할 때 버그들이 생길 수 있다고 한다. 이러한 위험성이 있기 때문에 리액트는 함수형 컴포넌트로 바꾼 근거가 되지 않을까 생각이 들었다. 
    • 또 다른 이유는 상태와 생명주기가 인스턴스에 종속이 되어있다는 것이다. 리액트는 하나의 컴포넌트를 객체화를 인스턴스화를 해야만 상태와 생명주기를 추적할 수 있기 때문에 문제가 생긴다. -> 이는 생명주기를 직접관리해야 하는 수고로움이 생길 수 있고, 중단 / 재개 등이 어려울 수 있다. 

     

    '프론트엔드' 카테고리의 다른 글

    React 딥다이브  (1) 2025.10.17
    React 딥다이브  (1) 2025.10.16
    React 딥다이브  (0) 2025.10.15
    Next Image 최적화와 SVG  (0) 2025.10.12
    불필요한 렌더링으로 인한 UI 버벅임 개선하기  (0) 2025.10.10
Designed by Tistory.