Class Component 의 Lifecycle Method

nara_lee·2025년 3월 4일
0

Lifecycle Method의 이해

Only avaiable in Class Component. For Function Component, use Hook instead.

  • Will = prior to some task; Did = after some task

  • 3 Categories: mount, update, unmount

  • 4 Things that trigger UPDATE

    • props changed
    • state changed
    • parent component re-rendered
    • force render by this.forceUpdate

Lifecycle Method 살펴보기

Total 9 of them.

render()

render(){...}
  • Only Method that is required.
  • You can access this.props and this.state in this method.
  • It returns react element. (tags like div or customized component) It can also return null or false. (displays nothing)
  • ⚠️ You CANNOT use setState outside event setter, nor access browser's DOM. If you want to access DOM information or change state, do it in componentDidMount()

constructor()

constructor(props) {...}

getDerivedStateFromProps()

static getDerivedStateFromProps(nextProps, prevState){
  if(nextProps.value !== prevState.value){ //조건에 따라 특정 값 동기화
    return {value: nextProps.value};
  }
  return null;
}

componentDidMount()

componentDidMount(){...}

이 안에서 다른 자바스크립트 라이브러리 또는 프레임워크의 함수를 호출하거나 이벤트 등록, setTimeout, setInterval, 네트워크 요청 같은 비동기 작업을 처리하면 된다.

shouldComponentUpdate()

shouldComponentUpdate(nextProps, nextState){...}
  • Must return T/F
  • 현재: this.props, this.state 으로 접근; 새로 설정될: nextProps, nextState으로 접근.
  • 프로젝트 성능 최적화 시, 상황에 맞는 알고리즘을 작성하여 리렌더링을 방지할 때는 false 반환.

getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate(prevProps, prevState){
  if(prevState.array !== this.state.array) {
    const {scrollTop, scrollHeight} = this.list
    return {scrollTop, scrollHeight};
  }
  return null;
}

주로 업데이트 직전의 값을 참고할 일이 있을 때 활용된다.

componentDidUpdate()

componentDidUpdate(prevProps, prevState, snapshot){...}

업데이트가 끝난 직후이므로, DOM 관련 처리를 해도 무방. (≈componentDidMount())

componentWillUnmount()

componentWillUnmount(){...}

componentDidCatch()

componentDidCatch(error, info){
  this.setState({
    error: true
  });
  console.log({error, info});
}
  • error: informs what kind of error occured
  • info: informs which code triggered error
  • console.log() 대신 서버 API를 호출하여 따로 호출 가능
  • ⚠️ 컴포넌트 자신에게 발생하는 에러를 잡아낼 수 없고 자신의 this.props.children으로 전달되는 컴포넌트에서 발생하는 에러만 잡아낼 수 있다

실습

//App.js
import { 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;
  • getDerivedStateFromProps() 는 부모에게서 받은 color 값을 state에 동기화
  • getSnapshotBeforeUpdate() 은 DOM에 변화가 일어나기 직전의 색상 속성을 snapshot 값으로 반환하여 componentDidUpdate() 에서 조회 가능케 함.
  • shouldComponentUpdate() 에서는 state.number 값의 마지막 자리수가 4이면 리렌더링 취소하게 함

  • React.StrictMode 때문에 일부 lifecycle이 두 번씩 호출됨.

componentDidCatch() 로 에러 잡기

// LifeCycleSample.js
...
return (
  <div>
    {this.props.missing.value} // undefined
  ...
  </div>
...
)

만약 이렇게 Component 안에서 에러를 일부러 내면 어떨까?

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

class ErrorBoundary extends Component {
  state = {
    error: false,
  };
  componentDidCatch(error, info) {
    this.setState({
      error: true,
    });
    console.log({ error, info });
  }
  render() {
    if (this.state.error) return <div>ERROR! ERROR!!</div>;
    return this.props.children;
  }
}

export default ErrorBoundary;
// App.js
return (
...
  <ErrorBoundary>
    <LifeCycleSample color={this.state.color} />
  </ErrorBoundary>
...
)

이렇게 감싸주자. (에러가 안나면 this.props.children 을 반환한다.)

콘솔에는 Error 랑 Object (info)가 찍힌다.


본 후기는 [한글과컴퓨터x한국생산성본부x스나이퍼팩토리] 한컴 AI 아카데미 (B-log) 리뷰로 작성 되었습니다.

#한컴AI아카데미 #AI개발자 #AI개발자교육 #한글과컴퓨터 #한국생산성본부 #스나이퍼팩토리 #부트캠프 #AI전문가양성 #개발자교육 #개발자취업

0개의 댓글