2 minute read

7장 컴포넌트의 라이프사이클 메서드

라이프사이클 메서드의 이해

  • 라이프사이클 메서드는 클래스형 메서드에서만 사용 할 수 있습니다.

  • 추후 배울 Hooks로 대체 할 수 있습니다.

  • 다음 장의 Hooks가 더 중요해서 간결하게 정리하고 넘어갈 예정입니다.

  • 분류 : 마운트(Mount), 업데이트(Update), 언마운트(UnMount) 로 구분됨.

    • 마운트 : DOM이 생성되고 웹 브라우저 상에 나타나는 것을 ‘마운트’ 라고 합니다.

    • 업데이트 : 컴포넌트는 네 가지 상황에 업데이트합니다.

      • props, state가 바뀔 때
      • 부모 컴포넌트가 리렌더링 될 때
      • this.forceUpdate로 강제로 렌더링을 트리거할 때
    • 언마운트 : 컴포넌트를 DOM에서 제거하는 것을 의미합니다.

라이프사이클 메서드 컴포넌트 변경 - Typescript Version

LifeCycleSample.tsx

import React, { createRef, Component } from 'react';

// 상위 컴포넌트에서 string 값으로 랜덤 색상을 보내준다 ex - '#243545'
interface Props{
    color : string;
}

// number는 4 번 마다 업데이트 하지 않기 위해 만든 것입니다.
// color는 props에서 주어준 색상을 이식하기 위해서입니다.
interface State{
    number : number;
    color : string;
}

class LifeCycleSample extends Component<Props, State> {
    state : State = {
        number : 0,
        color : 'black',
    }

    myRef = createRef<HTMLDivElement>(); 
    // 참고 할 'DOM' 객체는 'div'라는 것을 알려줍니다.

    // 클래스형 컴포넌트에서 'constructor' 사용 시,
    // 무조건 'super'을 써서 'props'를 보내 줘야 합니다.
    constructor(props : Props){
        super(props); 
        console.log('constructor');
    }

    // props로 받아 온 값을 state에 동기화시키는 용도로 사용합니다.
    // 컴포넌트가 마운트될 때와 업데이트 될 때 호출됩니다.
    // 밑의 예시는 props로 받아온 색깔과 현재 state의 색깔이 다를 경우, 리렌더링 합니다.
    // 색깔이 같을 확률이 매우 낮으므로 대부분 리렌더링 한다고 생각하시면 편합니다. - 여기에서만
    static getDerivedStateFromProps(nextProps : Props, prevState : State) {
        console.log('getDerivedStateFromProps');
        if(nextProps.color !== prevState.color) {
            return { color : nextProps.color }
        }
        return null;
    }

    //주로 비동기 작업을 넣습니다 - 라이브러리, 다른 프레임워크 함수 호출, 이벤트 등록, 네트워크 요청...
    componentDidMount() {
        console.log('componentDidMoutn');
    }

    // props or state를 변경 했을 때, 리렌더링을 시작할지 여부를 지정하는 메서드입니다.
    // state 의 number를 10으로 나눴을 때, 4, 14, 24 등등 일때, 리렌더링 하지 않습니다.
    shouldComponentUpdate(nextProps : Props, nextState : State) {
        console.log('shouldComponentUpdate', nextProps, nextState);
        return nextState.number % 10 !== 4;
    }

    // 컴포넌트를 DOM 에서 제거 할 때 실행합니다.
    componentWillUnmount() {
        console.log('componentWillUnmount');
    }

    // 클릭 할 때마다 state의 number를 1 씩 상승시킵니다.
    handleClick = () => {
        this.setState({
            number : this.state.number + 1
        })
    }

    // render에서 만들어진 결과물이 브라우저에 실제로 반영되기 직전에 호출됩니다.
    // 이 메서드에서 반환하는 값은 'componentDidUpdate'에서 snapshot 값으로
    // 전달받을 수 있습니다.
    getSnapshotBeforeUpdate(prevProps : Props, prevState : State) {
        console.log('getSnapshotBeforeUpdate');
        if(prevProps.color !== prevState.color) {
            return prevProps.color;
        }
        return null;
    }

    // 리렌더링을 완료한 후에 실행합니다.
    // 여기서 접근하는 props나 state는 컴포넌트가 이전에 가졌던 속성을 의미합니다.
    componentDidUpdate(prevProps : Props, prevState : State, snapshot : State) {
        console.log('componentDidUpdate', prevProps, prevState);
        if(snapshot) {
            console.log('업데이트 되기 직전 생상 : ', snapshot);
        }
    }

    render(){
        console.log('render');

        const style = {
            color : this.props.color
        }

        return (
            <div>
                <h1 style={style} ref={this.myRef}>
                    {this.state.number}
                </h1>
                <p>color : {this.state.color}</p>
                <button onClick={this.handleClick}>
                    더하기
                </button>
            </div>
        )
    }
};
export default LifeCycleSample;
  • 그리고, 이를 사용하기 위한 App.tsx 파일은 여기까지 보신 분들이라면 손쉽게 변환이 가능합니다.

App.tsx

import React, {Component} from 'react';
import LifeCycleSample from './LifeCycleSample';

function getRandomColor() : String {
    return '#' + Math.floor(Math.random() * 16777215).toString(16);
}

interface StateIFace {
    color : string
}

class App extends Component {
    state = {
        color : '#000000'
    }

    handleClick = () : void => {
        this.setState({
            color : getRandomColor()
        });
    }

    render() : JSX.Element {
        return (
            <div>
                <button onClick={this.handleClick}>랜덤 색상</button>
                <LifeCycleSample color={this.state.color} />
            </div>
        )
    }
}
export default App;

결과물

ramdomResult


  • 이후에 있는 ErrorBoundary.tsx 파일은 여러분이 직접 만들어보시기 바랍니다!

  • 여기까지 잘 읽어주신 분은 추후에도 충분히 잘 적용할 수 있습니다.

  • 만약에, 타입을 모르시겠다면, 인터넷에 변수의 이름과 타입을 영어로 치시면 쉽게 파악할 수 있습니다.

  • 참고로, 다음 예제의 error 타입은 unknown 타입이 아니며, boolean 속성입니다.

Updated: