꾸준히 성장하는 개발자

Component Lifecycle 본문

React

Component Lifecycle

ahleum 2022. 1. 21. 04:30

리액트 컴포넌트는 탄생부터 죽음까지 여러지점에서

개발자가 작업이 가능하도록 메서드를 오버라이딩 할 수 있게 해준다.

 

 

Declarative 디클레러티브

Component 생성 및 마운트 (< v16.3)

constructor

componentWillMount

render (최초 랜더)

componentDidMount

 

class App extends React.Component {
  _interval;

  constructor(props) {
    console.log('App constructor');
    super(props);
    this.state = {
      age: 37,
    };
  }

  componentWillMount() {
    console.log('App componentWillMount');
  }

  componentDidMount() {
    console.log('App componentDidMount');
    this._interval = window.setInterval(() => {
      this.setState({
        age: this.state.age + 1,
      });
    }, 1000);
  }

  componentWillUnmount() {
    console.log('App componentWillUnmount');
    clearInterval(this._interval);
  }

  render() {
    console.log('App render');
    return (
      <div>
        <h2>
          Hello {this.props.name} - {this.state.age}
        </h2>
      </div>
    );
  }
}

Component props, state 변경 (< v16.3)

componentWillReceiveProps

shouldComponentUpdate

componentWillUpdate
render

componentDidUpdate

 

componentWillReceiveProps(nextProps) {
    console.log(
      `App componentWillReceiveProps : ${JSON.stringify(
        this.props
      )} => ${JSON.stringify(nextProps)}`
    );
  }

  shouldComponentUpdate(nextProps, nextState) {
    console.log(
      `App shouldComponentUpdate : ${JSON.stringify(
        this.props
      )} => ${JSON.stringify(nextProps)}, ${JSON.stringify(
        this.state
      )} => ${JSON.stringify(nextState)}`
    );
    return true;
  }

  componentWillUpdate(nextProps, nextState) {
    console.log(
      `App componentWillUpdate : ${JSON.stringify(
        this.props
      )} => ${JSON.stringify(nextProps)}, ${JSON.stringify(
        this.state
      )} => ${JSON.stringify(nextState)}`
    );
  }

  componentDidUpdate(prevProps, prevState) {
    console.log(
      `App componentDidUpdate : ${JSON.stringify(
        prevProps
      )} => ${JSON.stringify(this.props)}, ${JSON.stringify(
        prevState
      )} => ${JSON.stringify(this.state)}`
    );
  }

componentWillReceiveProps

  • props 를 새로 지정했을 때 바로 호출됩니다.
  • 여기는 state 의 변경에 반응하지 않습니다.
    • 여기서 props 의 값에 따라 state 를 변경해야 한다면,
      • setState 를 이용해 state 를 변경합니다.
      • 그러면 다음 이벤트로 각각 가는것이 아니라 한번에 변경됩니다.

shouldComponentUpdate

  • props 만 변경되어도 실행   
  • state 만 변경되어도 실행
  • props & state 둘다 변경되어도 실행
  • newProps 와 new State 를 인자로 해서 호출
  • return type 이 boolean 입니다.
    • true 면 render
    • false 면 render 가 호출되지 않습니다.
    • 이 함수를 구현하지 않으면, 디폴트는 true

componentWillUpdate (render 전)

  • 컴포넌트가 재 랜더링 되기 직전에 불립니다.
  • 여기선 setState 같은 것을 쓰면 아니됩니다.

componentDidUpdate   (render 후)

  • 컴포넌트가 재 랜더링을 마치면 불립니다.

Component 언마운트 (< v16.3)

componentWillUnmpunt

 

class App extends React.Component {
  _interval;

  constructor(props) {
    console.log('App constructor');
    super(props);
    this.state = {
      age: 37,
    };
  }

  componentDidMount() {
    console.log('App componentDidMount');
    this._interval = window.setInterval(() => {
      this.setState({
        age: this.state.age + 1,
      });
    }, 1000);
  }
  
  componentWillUnmount() {
    console.log('App componentWillUnmount');
    clearInterval(this._interval);
  }

  render() {
    console.log('App render');
    return (
      <div>{this.state.age < 50 && <Button />}</div>
    );
  }
}
componentWillUnmount

class Button extends React.Component {
  componentWillUnmount() {
    console.log('Button componentWillUnmount');
  }

  render() {
    return <>hello</>;
  }
}

 

Component 라이프사이클 변경 (v16.3)

constructor

componentWillMount => getDerivedStateFromProps :특별한경우에 사용-시간의 흐름에 따른 props의 state에 따른?

render 

componentDidMount

 

componentWillReceiveProps => getDerivedStateFromProps

shouldComponentUpdate

render

componentWillUpdate => getSnapshotBeforeUpdate

(dom 에  적용)

componentDidUpdate

 

componentWillUnmount

 

Component 생성 및 마운트 (v16.3)

constructor

static getDerivedStateFromProps

render (최초 랜더)

componentDidMount

import React from 'react';

class App extends React.Component {
  state = {
    age: 0,
  };

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

    return null;
  }

  render() {
    console.log('App render');
    return <div>{this.state.age}</div>;
  }
}

export default App;

 

Component props, state 변경 (v16.3)

static getDerivedStateFromProps​ (props 변경)

shouldComponentUpdate (state 변경)
render

getSnapshotBeforeUpdate

(dom 에 적용)

componentDidUpdate

import React from "react";
import "./App.css";

let i = 0;

export default class App extends React.Component {
  state = { list: [] };

  getSnapshotBeforeUpdate(prevProps, prevState) {
    if (prevState.list.length === this.state.list.length) return null;
    const list = document.querySelector("#list");
    return list.scrollHeight - list.scrollTop;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    if (snapshot === null) return;
    const list = document.querySelector("#list");
    list.scrollTop = list.scrollHeight - snapshot;
  }

  componentDidMount() {
    setInterval(() => {
      this.setState({
        list: [...this.state.list, i++],
      });
    }, 1000);
  }

  render() {
    return (
      <div id="list" style={{ height: 100, overflow: "scroll" }}>
        {this.state.list.map((i) => (
          <div>{i}</div>
        ))}
      </div>
    );
  }
}

 

 

Component 언마운트 (v16.3)

componentWillUnmount

 

 

Component 에러 캐치 

Error Boundaries 에러바운더리 라이브러리

componentDidCatch    -문제가 생겼을때 에러화면이 보여진다던가 할 수 있음

import React from 'react';

class Button extends React.Component {
  render() {
    test();
    return <div>hello</div>;
  }
}

class App extends React.Component {
  state = {
    hasError: false,
  };

  componentDidCatch(error, info) {
    // Display fallback UI
    this.setState({ hasError: true });
    // You can also log the error to an error reporting service
    // logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      return <div>에러 화면</div>;
    }
    return (
      <div>
        <Button />
      </div>
    );
  }
}

export default App;

https://slides.com/woongjae/react2021#/11/12 참고 패스트캠퍼스 강의 듣는중 정리

'React' 카테고리의 다른 글

ESLint  (0) 2022.01.22
[react] CDN, create-react-app 두가지 방법으로 사용하기  (0) 2022.01.21
react Event Handling  (0) 2022.01.14
react 준비  (0) 2022.01.09
react 하는일  (0) 2022.01.09