Javascript/React 지식

[React] 컴포넌트의 생명주기로 본 NewCounter 예제

isfp_yykkng 2023. 4. 23. 13:43

컴포넌트의 생명주기로 본 NewCounter 예제

예제 구현 코드

App.js

//App.js
import React, { Component } from "react";
import NewCounter from "./03/NewCounter";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 10,
    };
    this.resetCount = this.resetCount.bind(this);
  }
  resetCount() {
    this.setState(({ count }) => ({ count: count + 10 }));
  }
  render() {
    return (
      <div>
        <NewCounter count={this.state.count} />
        <button onClick={this.resetCount}>
          {this.state.count + 10} 으로 초기화
        </button>
      </div>
    );
  }
}

export default App;

NewCounter.js

import React, { Component } from "react";

class NewCounter extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.increaseCount = this.increaseCount.bind(this);
  }
  static getDerivedStateFromProps(props, state) {
    const { count } = props;
    return {
      count,
      newCount: count === state.count ? state.newCount : count,
    };
  }
  increaseCount() {
    this.setState(({ newCount }) => ({
      newCount: newCount + 1,
    }));
  }
  render() {
    return (
      <div>
        현재 카운트 : {this.state.newCount}
        <button onClick={this.increaseCount}>카운트 증가</button>
      </div>
    );
  }
}

export default NewCounter;

컴포넌트 생명주기 관점에서 코드 해석

1) App 컴포넌트 생성해서 화면에 그릴 때 NewCounter 컴포넌트

 

App 컴포넌트 생성하면서 App 컴포넌트의 constructor에 의해서 App 컴포넌트의 state에 { count : 10 } 이 저장된다. 동시에 App 컴포넌트에서 <NewCounter count={this.state.count} /> 를 이용해서 하위 컴포넌트인 NewCounter 를 생성한다. 처음에 생성했을 때 NewCounter 컴포넌트의 constructor 의 state에는 { }로 빈 객체를 반환하기 때문에 NewCounter의 state에는 아무것도 없는 undefined 이다. 

2) NewCounter 컴포넌트 생성해서 화면에 그리기

 

NewCounter 컴포넌트가 생성되어서 constructor 이후 getDerivedStateFromProps() 함수를 통해서 NewCounter의 state값을 반환한다. 이때 count는 App 컴포넌트에서 props로 받은 10이고 newCount는 count값인 10과 state.count에 담겨있는 undefined로 같지 않기 때문에 count에 있는 값이 들어간다. 따라서 NewCounter의 state엔 {  count : 10, newCount : 10 }이 들어간다. 

3) NewCounter에서 카운트 증가 버튼을 클릭

 

NewCounter에서 카운트 증가 버튼을 클릭한다면 increaseCount() 함수가 실행되면서 setState()가 실행된다.  이에 따라 newCount의 값이 1 증가된다. setState() 함수 실행으로 갱신이 발생하고 newCounter의 getDerivedStateFromProps() 을 실행하여 NewCounter 컴포넌트의 state엔 { count : 10, newCount : 11 } 이 들어간다.

4) App 에서 20으로 초기화 버튼을 클릭

 

 App 에서 20으로 초기화 버튼을 클릭한다면 resetCount() 함수가 실행되면서 setState()가 실행된다. 이에 따라 count의 값이 20으로 변경된다. setState() 함수 실행으로 갱신이 발생하고 App의 getDerivedStateFromProps() 을 실행하여 App 컴포넌트의 state에 { count : 20 } 이 들어간다. NewCounter에서 props로 받는 count 값이 바뀌었기 때문에 NewCounter 컴포넌트의 count값도 20으로 변경되면서 getDerivedStateFromProps() 가 실행된다.  또한 App 컴포넌트에서 count 값에 따라 20으로 초기화 버튼은 30으로 초기화 버튼으로 변경된다.

NewCounter의 getDerivedStateFromProps() 에서 props로 받은 count는 20이고 현재 NewCounter의 state.count 값은 10이기 때문에 두 값이 같지 않아 false가 된다. 이에 따라 newCount 는 count의 값을 받아 20이 된다. 이 과정을 거치면서 반환값으로 NewCounter 컴포넌트의 state엔 { count : 20, newCount : 20 } 이 들어간다.

요약 : 컴포넌트 생성 > 카운트 증가 버튼 클릭으로 state 값이 바뀌면서 갱신 > NewCounter rerendering > 20으로 초기화 버튼 클릭 > App의 state 변경으로 갱신 > 30으로 초기화로 버튼이 변경됨 (App rerendering) + NewCounter의 props 값 변경 > NewCounter의 갱신 > NewCounter rerendering 

 

해당 결과에 따른 사진은 아래와 같다. 아래 console창을 보면 NewCounter의 state값의 변화를 볼 수 있다.