React | State Lifecycle / 생명주기

space's pace·2022년 6월 1일
0

React

목록 보기
1/8


[참고] https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

리액트 컴포넌트 생명주기


모든 리액트 컴포넌트에는 라이프 사이클을 가진다. 컴포넌트의 수명은 페이지에 렌더링되기 전 준비 과정에서 시작해 컴포넌트가 페이지에서 사라질 때 끝난다.
즉, 특정 시점에 코드가 실행되도록 설정할 수 있다는 것이다.


생명주기 (Life Cycle) 메소드를 사용하는 경우

1. 컴포넌트를 처음으로 렌더링 할 때
2. 컴포넌트를 업데이트 하기 전 / 후, 작업을 처리해야 할 때
3. 불필요한 업데이트 방지

Lifecycle에는 Class component를 사용한다.

🖍 알고 가기

 will 접두사가 붙은 메소드 >> 어떤 작업을 작동하기 전에 실행
 Did 접두사가 붙은 메소드 >> 어떤 작업을 작동한 후에 실행

React의 각 컴포넌트는 3가지 주요 단계를 통해 주기를 관리하고 관찰할 수 있다.


3가지 주기란, Mounting, Updating, Unmounting을 의미한다.



Mouting

: DOM이 생성되고 웹 브라우저상에 나타나는 것을 Mount 라고한다.


React는 컴포넌트를 마운팅할 때 순서대로 4가지 내장 메소드를 호출하게 된다.

  1. constructor()
  2. getDerivedStateFromProps()
  3. render()
  4. componentDidMount()

render() 메소드는 항상 호출 되어야하고, 다른 메소드들은 선택적 으로 호출 될 수 있다.


1. constructor(props)

: 컴포넌트를 새로 만들 때마다 먼저 호출되는 클래스 생성자 메소드

constructor() 메소드는 props 라고도 불리며, super(props) 를 가장 먼저 호출해야 한다. state 와 다른 초기 값들을 세팅한다. super(props) 는 부모의 constructor 메소드를 초기화하고, 부모로부터 상속받은 메소드들을 컴포넌트로 하여금 사용할 수 있도록 해준다.

2. getDerivedStateFromProps

: props 에 있는 값을 state 에 넣을 때 사용하는 메소드

컴포넌트 마운트 또는 업데이트에서 render 메소드를 호출하기 전에 호출되며 시간의 흐름에 따라 변하는 props를 state에 동기화하기 위해 존재하는 메소드

DOM에서 요소들이 랜더링 되기 직전에 호출되며, 최초의 props 에 기반한 state 객체를 저장한다. state 를 인자로 받고, state 가 변하면 객체를 반환한다. static과 함께 선언되어야 하며 메소드 내부에서는 this를 통한 인스턴스 접근이 불가하다. 또한, props를 이용하여 생성한 객체를 반환함으로써 props를 state에 동기화한다.

❌ React에서 이 메소드를 권장하지 않음!

3. render

: 필수값이며, DOM에 HTML을 표현함.
jsx를 반환 (배열, null 등 다른 요소 반환 가능)

컴포넌트 마운트 또는 업데이트에서 호출되며, shouldComponentUpdate() 가 false를 반환하는 경우에 호출되지 않는다.

UI 렌더링을 위해 필요한 메소드로 React Element를 반환한다. 컴포넌트의 상태를 변경하지 않아야 하며, 호출될 때마다 동일한 결과를 반환해야 하고 브라우저와 직접적인 상호작용을 하지 않아야 한다.

4. componentDidMount

: 컴포넌트가 웹 브라우저상에 나타난 후 호출하는 메소드

라이브러리 또는 프레임워크 함수 호출, 이벤트 등록, setTimeout, setInterval, 네트워크 요청 등의 비동기 작업을 처리하기에 적절한 메소드.

setState()를 호출하는 경우도 있지만, 추가 렌더링이 발생하여 성능 저하로 이루어질 수 있으므로 주의해야 함. (+ 무한루프)


Updating


: 컴포넌트가 상태나 props가 변경될 때, 즉, 업데이트 할 때를 의미한다.


5가지 내장 메소드가 있고, 컴포넌트가 업데이트 되면 순서대로 실행된다.

  1. getDerivedStateFromProps()
  2. shouldComponentUpdate()
  3. render()
  4. getSnapshotBeforeUpdate()
  5. componentDidUpdate()

1. getDerivedStateFromProps

: 컴포넌트가 업데이트 될 때 제일 먼저 호출되는 메소드.
초기 props에 기반한 state 가 저장되는 곳.

2. shouldComponentUpdate(props, state)

: render 메소드 호출 직전에 호출되며, 해당 컴포넌트를 리렌더링 할지를 결정하는 메소드.
기본 값은 true 이다. 성능 최적화를 위해 사용한다.

this.props와 props, this.state와 state의 비교에 따라 false를 반환하는 경우 render()가 호출되지 않아 리렌더링이 이루어지지 않는다.

렌더링을 방지하는 목적으로 사용하는 경우 버그로 이어질 수 있다.
이 때에는 PureComponent를 사용하는 것이 좋다.

3. render

컴포넌트가 업데이트 되면 역시 render() 도 호출된다. 새로운 변경대로 리랜더링 된다.

4. getSnapshotBeforeUpdate(props, state)

: 마지막으로 렌더링 된 결과가 DOM에 반영되기 전에 호출되는 메서드

업데이트 되기 전의 props와 state에 접근할 수 있다. 즉, update 이후에도 update 이전의 값들을 확인할 수 있다는 것. 스크롤 위치 등과 같은 정보를 변경되어 DOM에 반영되기 전에 얻을 수 있다.

만약 getSnapshotBeforeUpdate() 메소드가 존재하면, componentDidUpdate() 메소드도 포함해야 한다. 그렇지 않으면 ⛔️에러가 발생한다.

5. componentDidUpdate(props, state, snapshot)

: 컴포넌트가 DOM에서 update된 후에 호출

DOM을 조작하거나 이전과 현재의 props를 비교하여 네트워크 요청을 보낸다. setState를 호출할 수 있으나 조건문으로 감싸지 않으면, 무한 반복이 발생할 수 있으므로 주의해야 한다. shouldComponentUpdate()false를 반환하면 호출되지 않는다.



Unmounting


: 컴포넌트가 DOM을 제거하거나 DOM 상에서 완전히 제거(Unmount)될 때

React는 unmount 될 때 에서 단 하나의 메장 내소드를 갖고 있다.


componentWillUnmount()

: 컴포넌트가 언마운트되기 직전에 호출된다. 즉, 컴포넌트가 사라지기 전에 마지막으로 작업할 수 있는 메소드

componentDidMount()에서 설정한 모든 비동기 작업(이벤트, 타이머, 직접 생성한 DOM)에 대하여 정리를 해주어야 한다. 또한, 해당 컴포넌트는 리렌더링 되지 않으므로 setState를 호출하면 안 됌!




🤓 생명주기 메소드 사용법

  1. 그리기 → render 인풋창 그리기
  2. 그리고 난 뒤 → componentDidMount 포커스 깜빡 깜빡 하기
  3. 그리고 난 뒤 변경 → componentDidUpdate
  4. 그리고 난 뒤 사라짐 → componentWillUnmount

import { Component } from "react";
import Router from "next/router";

export default class CounterPage extends Component {
  state = {
    count: 99,
  };


	// 2. input태그 선택해서 포커스 깜빡거리게 하기
  componentDidMount() {
    console.log("마운트됨!!!");
  }


	// 3. 그리고 난 뒤 변경
  componentDidUpdate() {
    console.log("수정되고 다시그려짐!!!");
  }


	// 4. 그리고 난 뒤 사라짐
    // 채팅방 나가기, api 요청
  componentWillUnmount() {
    console.log("컴포넌트 사라짐!!!");
  }


	// 카운트 올리기 함수
  onClickCounter = () => {
    this.setState((prev) => ({
      count: prev.count + 1,
    }));
  };

	// 현재 페이지 나가기 함수 _ componentWillUnmount를 보기위한
  onClickMove() {
    Router.push("/");
  }

	// 1. 그리기
  render() {
    return (
      <div>
        <div> 현재카운트: {this.state.count}</div>
        <button onClick={this.onClickCounter}> 카운트 올리기</button>
        <button onClick={this.onClickMove}> 나가기</button>
      </div>
    );
  }
}

[참고한 블로그]
1. https://talking-potato.me/m/51?category=997827
2. https://serzhul.io/REACT/react-life-cycle(%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%83%9D%EB%AA%85-%EC%A3%BC%EA%B8%B0)/
3. https://velog.io/@youngminss/React-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0-%EB%A9%94%EC%84%9C%EB%93%9C

profile
블로그 이사 준비중!

0개의 댓글