김용현
Study

정리하기 파일

2장. 리액트 핵심 요소 깊게 살펴보기

JSX의 정의

  • JSXElement, JSXAttributes, JSXChildren, JSXStrings라는 4가지 컴포넌트를 기반으로 구성돼 있다.

JSXElement

  • JSX를 구성하는 가장 기본 요소로, HTML의 요소(element)와 비슷한 역할을 한다. JSXElement가 되기 위해서는 다음과 같은 형태 중 하나여야 한다.
    • JSXOpeningElement
    • JSXClosingElement
    • JSXSelfClosingElement
    • JSXFragment
  • JSXElementName
    • JSXElement의 요소 이름으로 쓸 수 있는 것을 의미.

JSXAttributes

  • JSXElement에 부여할 수 있는 속성을 의미.

JSXChildren

  • JSXElement의 자식 값을 나타낸다.

가상 DOM과 리액트 파이버

DOM과 브라우저 렌더링 과정

가상 DOM의 탄생 배경

가상 DOM을 위한 아키텍처, 리액트 파이버

  • 리액트 파이버란?
    • 리액트에서 관리하는 평범한 자바스크립트 객체
    • 재조정(reconciliation)이란?
      • 리액트에서 어떤 부분을 새롭게 렌더링해야 하는지 가상 DOM과 실제 DOM을 비교하는 작업(알고리즘)
    • 리액트 파이버의 목표
      • 리액트 웹 애플리케이션에서 발생하는 애니메이션, 레이아웃, 그리고 사용자 인터랙션에 올바른 결과물을 만드는 반응성 문제를 해결하는 것.
        • 작업을 작은 단위로 분할하고 쪼갠 다음, 우선순위를 매긴다.
        • 이러한 작업을 일시 중지하고 나중에 다시 시작할 수 있다.
        • 이전에 했던 작업을 다시 재사용하거나 필요하지 않은 경우에는 폐기할 수 있다.

클래스형 컴포넌트와 함수형 컴포넌트

클래스형 컴포넌트

  • 클래스형 컴포넌트의 생명주기 메서드
    - 마운트(mount) : 컴포넌트가 마운팅(생성)되는 시점
    - 업데이트(update) : 이미 생성된 컴포넌트의 내용이 변경(업데이트)되는 시점
    - 언마운트(unmount) : 컴포넌트가 더 이상 존재하지 않는 시점
    • render
    • componentDidMount
    • componentDidUpdate
    • componentWillUnmount
    • shouldComponentUpdate
    • static getDerivedStateFromProps
      • componentWillReceiveProps를 대체할 수 있는 메서드
      • render()를 호출하기 직전에 호출된다.
      • static으로 선언돼 있어 this에 접근할 수 없다. 여기서 반환하는 객체는 해당 객체의 내용이 모두 state로 들어가게 된다. 이에 반해 null을 반환하면 아무런 일도 일어나지 않는다.
    • getSnapShotBeforeUpdate
      • componentWillUpdate()를 대체할 수 있는 메서드
      • DOM이 업데이트되기 직전에 호출된다. 여기서 반환되는 값은 componentDidUpdate로 전달된다.
      • DOM에 렌더링되기 전에 윈도우 크기를 조절하거나 스크롤 위치를 조정하는 등의 작업을 처리하는 데 유용하다.
    • getDerivedStateFromError
      • 에러 상황에서 실행되는 메서드
      • 자식 컴포넌트에서 에러가 발생했을 때 호출되는 에러 메서드다.
      • 하위 컴포넌트에서 에러가 발생했을 경우에 어떻게 자식 리액트 컴포넌트를 렌더링할지 결정하는 용도로 제공되는 메서드이기 때문에 반드시 미리 정의해 둔 state 값을 반환해야 한다.
    • componentDidCatch
      • 자식 컴포넌트에서 에러가 발생했을 때 실행되며, getDerivedStateFromError에서 에러를 잡고 state를 결정한 이후에 실행된다.
      • 두개의 인수를 받는데, 첫 번째는 getDerivedStateFromError와 동일한 Error, 그리고 정확히 어떤 컴포넌트가 에러를 발생시켰는지 정보를 가지고 있는 info다.

    클래스형 컴포넌트의 한계

    • 데이터의 흐름을 추적하기 어렵다.
      • state가 어떤 식의 흐름으로 변경돼서 렌더링이 일어나는지 혹은 일어나지 않는지를 판단하기 어렵다.
    • 애플리케이션 내부 로직의 재사용이 어렵다.
    • 기능이 많아질수록 컴포넌트의 크기가 커진다.
    • 클래스는 함수에 비해 상대적으로 어렵다.
    • 핫 리로딩을 하는 데 상대적으로 불리하다.

    함수형 컴포넌트 vs 클래스형 컴포넌트

    • 생명주기 메서드의 부재
      • 클래스형 컴포넌트의 생명주기 메서드가 함수형 컴포넌트에서는 존재하지 않는다.
    • 함수형 컴포넌트와 렌더링된 값
      • 함수형 컴포넌트는 렌더링이 일어날 때마다 그 순간의 값인 props와 state를 기준으로 렌더링된다. props와 state가 변경된다면, 다시 한 번 그 값을 기준으로 함수가 호출된다고 볼 수 있다. 반면 클래스형 컴포넌트는 시간의 흐름에 따라 변화하는 this를 기준으로 렌더링이 일어난다.

    렌더링은 어떻게 일어나는가?

    리액트의 렌더링이란?

    • 리액트에서의 렌더링이란 리액트 애플리케이션 트리 안에 있는 모든 컴포넌트들이 현재 자신들이 가지고 있는 props와 state의 값을 기반으로 어떻게 UI를 구성하고 이를 바탕으로 어떤 DOM 결과를 브라우저에 제공할 것인지 계산하는 일련의 과정을 의미한다.

    리액트의 렌더링이 일어나는 이유

    • 리렌더링이 발생하는 경우
      • 클래스형 컴포넌트의 setState가 실행되는 경우
      • 클래스형 컴포넌트의 forceUpdate가 실행되는 경우
      • 함수형 컴포넌트의 useState()의 두 번째 배열 요소인 setter가 실행되는 경우
      • 함수형 컴포넌트의 useReducer()의 두 번째 배열 요소인 dispatch가 실행되는 경우
      • 컴포넌트의 key props가 변경되는 경우
        • 리렌더링이 발생하면 current 트리와 workInProgress 트리 사이에서 어떠한 컴포넌트가 변경이 있었는지 구별해야 하는데, 이 두 트리 사이에서 같은 컴포넌트인지를 구별하는 값이 바로 key다.
      • prop가 변경되는 경우

      렌더와 커밋

      • 렌더 단계
        • 컴포넌트를 렌더링하고 변경 사항을 계산하는 모든 작업
      • 커밋 단계
        • 렌더 단계의 변경 사항을 실제 DOM에 적용해 사용자에게 보여주는 과정
      • 리액트의 렌더링이 일어난다고 해서 무조건 DOM 업데이트가 일어나는 것은 아니다.