'리액트를 다루는 기술' 7장, 컴포넌트의 라이프사이클 메서드

Jake_Young·2020년 8월 20일
0
post-thumbnail

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

  • 컴포넌트를 처음 렌더링 할 떄, 작업을 처리해야 할 때
  • 컴포넌트를 업데이트 하기 전후로 어떤 작업을 처리해야 할 때
  • 라이프사이클은 클래스형 컴포넌트에서만 사용할 수 있다.
  • 함수형 컴포넌트에서는 Hooks를 사용한다.
  • Will 접두사가 붙은 것은 어떤 작업을 하기 전에 실행되는 메서드
  • Did 접두사가 붙은 것은 어떤 작업을 한 이후에 실행되는 메서드
  • 라이프 사이클은 총 세 가지, 즉 마운트, 업데이트, 언마운트 카테고리로 나뉜다.

마운트

  • constructor: 컴포넌트를 새로 만들 때마다 호출되는 클래스 생성자 메서드
  • getDerivedStateFromProps: props에 있는 값을 state에 넣을 때 사용하는 메서드
  • render: 우리가 준비한 UI를 렌더링하는 메서드
  • componentDidMount: 컴포넌트가 웹 브라우저상에 나타난 후 호출하는 메서드

업데이트

  • 컴포넌트가 업데이트 되는 경우
    1. props가 바뀔 때
    2. state가 바뀔 때
    3. 부모 컴포넌트가 리렌더링 될 때
    4. this.forceUpdate로 강제로 렌더링을 트리거할 때
  • getDerivedStateFromProps: (생략)
  • shouldComponentUpdate:
    • 렌더링 할 지 말 지를 결정하는 메서드.
    • boolean을 반환해야 하며 true를 반환하면 새로 렌더링 한다.
    • 만약 this.forceUpdate() 함수를 호출한다면 이 과정은 생략되고 바로 render 함수를 호출한다.
  • render: (생략)
  • getSnapshotBeforeUpdate:
    • 컴포넌트 변화를 DOM에 반영하기 직전에 호출되는 메서드이다.
    • 주로 스크롤바 위치 유지와 같은 용도로 쓴다.
  • componentDidUpdate: (생략)

언마운트

  • componentWillUnmount: (생략)

componentDidCatch

  • 렌더링 도중 에러가 발생하면 오류 UI를 보여줄 수 있게 한다.

🙄 라이프사이클 메서드 사용하기

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

export default 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 % 2 !== 1;
  }

  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("just before updating", snapshot);
    }
  }

  render() {
    console.log("render");
    const style = {
      color: this.props.color
    };
    return (
      <div>
        {/* {this.props.missing.value} */}
        <h1 style={style} ref={(ref) => (this.myRef = ref)}>
          {this.state.number}
        </h1>
        <p>color: {this.state.color}</p>
        <button onClick={this.handleClick}>plus</button>
      </div>
    );
  }
}


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

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

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

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

  render() {
    return (
      <div className="App">
        <button onClick={this.handleClick}>random color</button>
        <ErrorBoundary>
          <LifeCycleSample color={this.state.color} />
        </ErrorBoundary>
      </div>
    );
  }
}


// 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 occur</div>;
    return this.props.children;
  }
}

export default ErrorBoundary;
profile
자바스크립트와 파이썬 그리고 컴퓨터와 네트워크

0개의 댓글