[react] react의 생명주기

Ell!·2021년 10월 31일
0

react

목록 보기
3/28

react를 배운지 어언 4개월...(응애 나 애기 리액트 개발자😎) 맨 처음 리액트를 공부할 때, 너무 어렵다고 넘긴 리액트의 작동 원리를 이제금 제대로 정리를 해보려고 한다!

목차
1. 리액트 개별 컴포넌트의 생명주기
2. 리액트 전체 프로젝트의 작동원리
3. 리액트의 비교 방법

리액트 개별 컴포넌트의 생명주기

이 그림... 아마 많이 본 적 있을 것이다. 내가 처음 리액트를 공부할 때 리액트 진짜 어렵다! 라고 생각하게 했던 '그' 생명주기! 요거를 한 번 정리해보겠다.

@ 비록 함수형 컴포넌트를 사용하지만 생명주기를 설명하는 데에는 클래스형 컴포넌트가 더 알맞기 때문에 혼용해서 설명하기로 했다.

Mount - Update - Unmount

리액트 컴포넌트의 인스턴스는 세 단계를 거쳐서 진행된다.

가장 먼저 mount단계. 마운트는 DOM객체가 생성되고 브라우저에 나타나는 것을 의미한다. 마운트 단계에서 4개의 함수가 호출된다.

  • constructor : 컴포넌트 클래스의 생성자. state의 초기값을 지정
  • getDerivedStateFromProps : props와 state값 동기화
  • render : 컴포넌트의 기능과 모양새 정의. 리액트 요소를 반환
  • componentDidMount : 첫 랜더링이 끝났을 때 호출되는 함수

이 포스팅을 쓰게 한 이유였던, 마운트와 랜더링의 차이. 마운트는 컴포넌트에서 DOM을 성생하고 브라우저에 나타내는 과정이고, 랜더링은 그 중 한 단계로 브라우저에 그리는 단계를 말한다.

그 후 Update단계가 진행된다. 이 때, 5가지의 함수가 호출된다.

  • getDerivedStateFromProps
  • shouldComponentUpdate : true 반환하면 아래의 함수들을 호출하여 리랜더링 진행. false 반환하면 리랜더링 안 함
  • render : 새로운 값을 사용하여 re-rendering
  • getSnapshowBeforeUpdate : 변경된 요소에 대해 DOM객체에 반영 직전에 호출
  • componentDisUpdate : 컴포넌트 업데이터 작업이 끝난 후 리랜더링 후에 호출

마지막으로 Unmount단계.

  • componentWillUnmount : 해당 컴포넌트 제거 직전 호출

리액트 전체 프로젝트의 작동 원리

리액트를 가장 먼저 배우면서 제일 궁금한 점이 바로 이것이다.

리액트는 Vanilla JS와 무엇이 다른가요??

그럴때면 Virtual DOM이란 것을 사용해서 더 빠르고 효율적으로 랜더링을 할 수 있게 해준다고 한다. 자세히 살펴보자.

react 최초의 랜더링

  1. root directory의 index.js에 있는 ReacDOM.render를 호출한다.
  2. 여기서부터 마주친 Element들의 type을 검사한다.
    Dom Element (div 등) : 자식들도 동일한 과정으로 재귀 반복
    Component Element (<MyPage /> 등) : 해당 컴포넌트에 props를 제공해 Element tree를 얻는다. 여기서부터 다시 재귀적으로 반복
  3. 이 과정을 반복하여 Virtual Dom(element tree)을 얻는다

react re-rendering

react에서 re-rendering이 이루어지는 이유에는 4가지가 있다. props가 변경, state가 변경, forceUpdate()를 실행, 부모 컴포넌트가 랜더링될 때 이러한 이유에서 위에서 언급한 Update단계에 들어오게 되면 다음의 작업이 이루어진다.

  1. props, state가 변경되면 render()메소드의 호출로 새로운 엘리먼트 트리가 반환
  2. 새로운 엘리먼트 트리가 반활될 때마다 기존의 트리와 비교하기 위한 재조정 과정을 밟는다.
  3. 재조정 과정은 O(n)의 시간복잡도를 가지고 있다고 한다. shouldComponentUpdate를 적절히 활용해서 불필요한 render()메소드 호출을 막을 수 있다.

재조정(Reconciliation)

컴포넌트의 state, props 변경 시에 새로 반환되는 엘리먼트 트리와 이전 트리를 비교하여 변경점을 파악하고, 변경된 부분만 일괄 갱신한다. 이를 위해 O(n)이 걸리는 휴리스틱 알고리즘을 사용한다고 한다.

비교 알고리즘을 간략하게 설명하면,
1. 엘리먼트 타입이 다른 경우 : 이전 트리를 완전히 버리고 새로운 트리 구축. 이전 트리의 컴포넌트 인스턴스, state들은 모두 언마운트 / 삭제 됨.
2. 같은 타입의 DON 엘리먼트 : 동일한 부분은 유지, 변경된 부분들만 갱신.
3. 같은 타입의 컴포넌트 엘리먼트 : 컴포넌트 인스턴스는 동일하게 유지되어 랜더링 같 state가 유지. 새로운 엘리먼트 내용 반영 위해 현재 컴포넌트의 props 갱신. 재귀적으로shouldComponentUpdate를 호출하여 리랜더링할지 결정

자식 엘리먼트들에 대한 재귀적 처리는 다음의 특징을 지닌다고 한다.

  • 자식 엘리먼트 리스트 비교 시 두 리스트를 순회하여 차이점 파악
  • 각 리스트 엘리먼트는 구분을 위해 unique한 key 사용

참고문서

https://lktprogrammer.tistory.com/130

https://it-eldorado.tistory.com/83

https://medium.com/vingle-tech-blog/react-%EB%A0%8C%EB%8D%94%EB%A7%81-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f255d6569849

https://ideveloper2.tistory.com/159

https://velog.io/@naamoonoo/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%91%EB%8F%99%ED%95%A0%EA%B9%8C-Diffing-3%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0

profile
더 나은 서비스를 고민하는 프론트엔드 개발자.

0개의 댓글