[React] 라이프사이클 메서드 사용

🌊·2021년 12월 9일
0

React

목록 보기
8/20
post-custom-banner

라이프사이클 메서드 사용 예시

App.js

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

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

class App extends Component {
  state = {
    color: "#000000",
  };

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

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

export default App;

LifeCycleSample.js

import React, { Component } from "react";

class LifeCycleSample extends Component {
  state = {
    number: 0,
    color: null,
  };

  myRef = null;

  constructor(props) {
    super(props);
    console.log("constructor");
  }

  static getDerivedStateFromProps(nextProps, prevState) {
    console.log("getDerivedStateFromProps");
    if (nextProps.color !== prevState.color) {
      return { color: nextProps.color };
    }
    return null;
  }

  componentDidMount() {
    console.log("componentDidMount");
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log("shouldComponentUpdate", nextProps, nextState);

    return nextState.number % 10 !== 4;
  }

  componentWillUnmount() {
    console.log("componentWillUnmount");
  }

  handleClick = () => {
    this.setState({
      number: this.state.number + 1,
    });
  };

  getSnapshotBeforeUpdate(prevProps, prevState) {
    console.log("getSnapshotBeforeUpdate");
    if (prevProps.color !== this.props.color) {
      return this.myRef.style.color;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    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={(ref) => (this.myRef = ref)}>
          {this.state.number}
        </h1>
        <p>Color: {this.state.color}</p>
        <button onClick={this.handleClick}>더하기</button>
      </div>
    );
  }
}

export default LifeCycleSample;

라이프사이클 메서드 설명

처음 컴포넌트가 렌더링 될 때

호출되는 메서드 순서

1. constructor

부모 컴포넌트에서 받아온 props 값을 가지고 있다.
props 값은 컴포넌트의 state 값에 update 되지 않았다 (this.state의 color 값은 null이다.)

2. getDerivedStateFromProps

해당 메서드를 통해서 props 값을 state에 넣어주게 된다.
nextProps: 받아온 props 값을 가지고 있다.
prevState: 현재 컴포넌트가 가지고 있는 state 값을 가지고 있다.

3. render

렌더링하는 과정에서 값을 세팅해준다.

4. componentDidMount

모든 렌더링 과정이 진행됐을 때 실행된다.


랜덤색상 버튼을 눌렀을 때

호출되는 메서드 순서

1. getDerivedStateFromProps

부모 컴포넌트에서 랜덤으로 생성된 색상이 업데이트 되면서 props에 새로운 값이 전달된다.
컴포넌트의 state 값을 props의 새로운 값으로 업데이트한다.

2. shouldComponentUpdate

nextState.number % 10의 값이 4이면 리렌더링을 취소하고 나머지는 리렌더링을 진행한다.

3. render

렌더링하는 과정에서 값을 세팅해준다.

4. getSnapshotBeforeupdate

업데이트 직전의 값을 가지고 있다.
새로운 값이 아닌 이전의 값을 가지고 있다. 해당 값은 componentDidUpdate 메서드의 snapshot 파라미터로 값을 전달할 수 있다.

5. componentDidUpdate

업데이트 이후 호출되는 메서드
이전에 가졌던 값(데이터)에 접근할 수 있다.


더하기 버튼을 눌렀을 때

호출되는 메서드 순서

1. getDerivedStateFromProps

2. shouldComponentUpdate

3. render

4. getSnapshotBeforeUpdate

5. componentDidUpdate

변경되는 값의 내용만 다르고 호출되는 메서드의 순서는 랜덤색상 버튼을 눌렀을 때와 동일하다.
변환된 값을 보내주는 props 값으로 보내주는 것이 아니라 컴포넌트 내부에서 메서드를 통해서 값을 update 한다.


업데이트가 취소될 때

호출되는 메서드 순서

1. getDerivedStateFromProps

2. shouldComponentUpdate

shouldComponentUpdate 메서드에서 falsereturn되면 리렌더링을 취소한다.
getDerivedStateFromProps 메서드가 실행됐기 때문에 state 값은 이미 바뀌어 있다.

post-custom-banner

0개의 댓글