기은P
시간이 멈추는 장소
기은P
  • Programming (272)
    • 개발노트 (1)
    • FrontEnd (56)
      • ES&JS 문법 (14)
      • HTML&CSS (4)
      • React 기본 (18)
      • React 심화 (12)
      • React 이슈 (2)
      • Project 연습 (1)
      • Next.js (5)
    • Backend&Devops (33)
      • AWS (2)
      • Docker (9)
      • Jenkins (6)
      • Nginx (6)
      • Node.js (1)
      • ElasticSearch (5)
      • 프레임워크&아키텍처 (2)
      • 암호화 (0)
      • 기타 (2)
    • 알고리즘 (3)
    • C# (8)
      • WPF (8)
    • Java (51)
      • 순수 Java (18)
      • RDF&Jena (12)
      • RCP&GEF (9)
      • JMX (5)
      • JMapper (3)
      • 오류해결 (4)
    • Database (21)
      • RDBMS (9)
      • NoSQL (2)
      • TSDB (1)
      • GraphQL (1)
      • Hibernate (3)
      • 데이터베이스 이론 (4)
      • Redis (1)
    • 프로토콜 (11)
      • Netty (4)
      • gRPC (5)
      • 프로토콜 개념 (2)
    • Server (4)
      • Linux (4)
    • 2020 정보처리기사 필기 (43)
      • 목차 (1)
      • 기출문제 (1)
      • 1과목 - 소프트웨어 설계 (6)
      • 2과목 - 소프트웨어 개발 (7)
      • 3과목 - 데이터베이스 구축 (8)
      • 4과목 - 프로그래밍 언어 활용 (7)
      • 5과목 - 정보시스템 구축 관리 (10)
    • 2020 정보처리기사 실기 (31)
      • 목차 (4)
      • 기출예상문제 (19)
      • 실기요약 (8)
    • 빅데이터분석기사 필기 (4)
      • 목차 (0)
      • 필기 요약 (3)
    • 전기 공학 (1)
      • CIM (1)
    • 산업자동화시스템 (3)
      • SCADA (1)
      • OPC UA (2)
    • 디자인패턴 (1)
    • 휴지통 (0)

공지사항

  • 공지사항/포스팅 예정 항목

최근 댓글

최근 글

전체 방문자
오늘
어제

티스토리

hELLO · Designed By 정상우.
기은P

시간이 멈추는 장소

FrontEnd/React 심화

[React] 렌더링(리렌더링)

2022. 11. 3. 15:09
반응형

1. 개요

React를 공부하면서 어떻게 보면 가장 기초이고, 가장 중요한 부분인데 사실 이제야 포스팅한다는 것은 이제까지 리액트를 잘못 사용해왔다는 반증이기도 한데... 조금 더 심도있게 리액트를 알아보기 위해서 렌더링이란 무엇이고, 렌더링의 조건이 어떻게 되는 건지 확인차 적어보려고 합니다.

 

 

 

2. 렌더링이란?

아래의 Welcome을 컴포넌트라고 부릅니다. (정확히는 함수 컴포넌트)

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}

리액트에서 렌더링이란 컴포넌트가 현재 props와 state의 상태에 기초해 UI를 어떻게 구성할지, 컴포넌트에게 작업을 요청하는 것을 의미합니다.

 

 

3. 렌더링 과정

3-1. React의 렌더링

기본적인 리액트의 렌더링 개념은 루트(<div id="root"></div>) DOM부터 시작해 플래그가 지정되어 있는 모든 컴포넌트를 찾아서 렌더링을 진행하는 것을 말합니다.

* root id는 public/index.html에 기본적으로 설정이 되어있습니다.

* DOM은 HTML parser에 의해 생성된 트리 구조의 Node 객체 모델입니다.

 

const root = ReactDOM.createRoot(
  document.getElementById('root')
);
const element = <h1>Hello, world</h1>;
root.render(element);

기본적으로 리액트의 렌더링은 이러한 DOM 엘리먼트를 ReactDOM.createRoot()에 전달한 다음, 그 React Element를 root.render()에 전달하는 과정을 거칩니다.

 

 

 

 

3-2. React Element

자, 그럼 React Element는 무엇일까요? 리액트 엘리먼트는 type과 props를 가지는 React만의 객체입니다. React.creatElement()를 이용해 만들 수 있으며, type으로 HTML 태그 이름을 가지고, 그 이외의 특징을 props로 관리하는 객체 형태로 정의됩니다.

// createElement를 이용해서 React Element 만들기
React.createElement(
  'div',
  { className: 'name' },
  'React'
)
// 위와 같은 의미 (JSX 문법)
<div className='name'>React</div>


// createElement를 이용해서 만들어진 React Element 객체
{
  type: 'div',
  props: {
    className: 'name',
    children: 'React'
  }
}

사실 위와 같은 createElement()라는 함수를 사용하기가 어렵기도 하고, 직관적이지도 않습니다.

따라서 JSX 문법을 사용해 보통 위의 객체를 DOM 형태(<div className='name'>React</div>)로 정의하여 사용합니다.

이러한 리액트 엘리먼트는 불변객체로 작용해서, 엘리먼트가 생성된 이후에는 해당 엘리먼트의 속성과 자식을 변경할 수 없다는 특징을 가지게 됩니다.

 

 

 

3-2. Virtual DOM

리액트의 특징 중 하나의 가상 돔(Virtual DOM)은 실제 DOM의 구조와 비슷한 React 객체의 트리를 말합니다.

웹 브라우저에서 사용자는 여러 가지 액션을 통해 웹 서버에 요청하고, 그에 따른 응답으로 DOM 구조가 빈번하게 바뀌는데, 이때마다 DOM이 수정되어 Render Tree가 생성되고, Reflow, Repaint의 과정을 계속 수행하게 된다면 굉장히 답답한 상황이 발생하게 될 것입니다.

이때 React에서는 Virtual DOM을 실제 DOM에 필요한 부분만 적절하게 반영해서 불필요한 수정이 일어나지 않도록 해주는데, 이 Virtual DOM의 가장 큰 장점은 개발자가 직접 DOM을 조작하지 않아도 된다는 점이고, 이러한 과정을 모두 자동화해준다는 점입니다.

또한 DOM의 수정을 batch로 한 번에 처리하기 때문에 리렌더링 연산을 최소화 할 수 있습니다.

 

 

 

 

3-3. 재조정(Reconciliation)

앞서 설명한 Virtual DOM에서 어떻게 리액트는 실제 DOM과 가상 DOM을 구별하는지 궁금할 텐데, 결과적으로 브라우저에 렌더링을 할 때 어떻게 기존의 컴포넌트와 변경이 되었는지 확인하기 위해 리액트에서 diffing 알고리즘을 사용하여  이 알고리즘을 통해 컴포넌트의 갱신합니다.

리액트는 아래의 2가지 가정을 기반으로 O(n)의 시간복잡도를 가지는 휴리스틱 알고리즘을 구현했습니다.

 

  1. 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어 낸다.
  2. 개발자가 key prop을 통해 컴포넌트 인스턴스를 식별하여, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야할지 표시해 줄 수 있다.

위의 재조정 단계를 거쳐 이전 elements와 새로 생성된 elements를 비교해 엘리먼트가 변경되었다면 렌더링을 수행합니다.

 

 

 

 

 

4. 리렌더링

앞에서 렌더링을 설명했는데, 리액트에선 초기에 한번 렌더링을 진행하고, 그 이후에 특정 조건이 발생하면 다시 렌더링을 진행하는 리렌더링이라고 하는 것이 있습니다.

  • 내부 상태(state) 변경시
  • 부모에게 전달받은 값(props) 변경시
  • 중앙 상태값(Context value 혹은 redux store) 변경시
  • 부모 컴포넌트가 리렌더링 되는 경우

위의 경우가 컴포넌트가 리렌더링 되는 조건입니다.

 

리액트가 아무리 최적화가 잘 되어있다고해도, 무분별하게 렌더링이 일어날 경우 성능 저하가 일어나게 되기 때문에, 이러한 조건들을 기준을 두고 코드를 작성하여 무분별하게 렌더링이 일어나지 않도록 주의하여야 합니다.

* redux store 변경시 자동으로 리렌더링이 되는 이유는, 리덕스 스토어가 <Provider store={store}>로 컴포넌트를 감싸주었을 때, 스토어 상태가 변경될 때마다 이를 참조하는 컴포넌트들이 리렌더링이 될 수 있도록 react-redux 라이브러리가 자동적으로 컴포넌트 들의 렌더 함수들을 subscribe 해주기 때문입니다.

 

 

4-1. 리렌더링 과정

  1. 위의 조건을 통해 컴포넌트 리렌더링
  2. 구현부 실행 = props 취득, hook 실행, 내부 변수 및 함수 재 생성
  3. return 실행, 렌더링 시작
  4. 렌더 단계(Render Phase): 새로운 가상 DOM 생성 후 이전 가상 DOM과 비교해 달라진 부분을 탐색하고 실제 DOM에 반영할 부분을 결정
  5. 커밋 단계(Commit Phase): 달라진 부분만 실제 DOM에 반영
  6. useLayoutEffect: 브라우저가 화면에 Paint하기 전에 useLayoutEffect에 등록해둔 effect(부수 효과 함수)가 동기적으로 실행되며, 이때 state, redux store 등의 변경이 있다면 한번 더 리렌더링
  7. Paint: 브라우저가 실제 DOM을 화면에 그림. didUpdate 완료.
  8. useEffect: update되어 화면에 그려진 직후, useEffect에 등록해둔 effect(부수 효과 함수)가 비동기로 실행

 

 

 

 

 

 

 

반응형
저작자표시 변경금지 (새창열림)

'FrontEnd > React 심화' 카테고리의 다른 글

[React] HOC(고차 컴포넌트) 함수형 예제  (0) 2022.11.15
[React] useMemo와 useCallback의 차이  (5) 2022.11.03
[React] SEO 처리 하기  (0) 2022.10.19
[React] SSR과 CSR(SPA) 차이  (0) 2022.10.19
[React] Redux Toolkit 에서의 비동기 처리(createAsyncThunk, extraReducers)  (0) 2022.09.19
    'FrontEnd/React 심화' 카테고리의 다른 글
    • [React] HOC(고차 컴포넌트) 함수형 예제
    • [React] useMemo와 useCallback의 차이
    • [React] SEO 처리 하기
    • [React] SSR과 CSR(SPA) 차이
    기은P
    기은P
    기은P의 블로그 일상과 개발 관련 포스팅 #React #Typescript #Next #Nest https://github.com/kimdongjang

    티스토리툴바