s

리엑트 스터디(JSX, React Fiver)

Chapter 02 리액트 핵심 요소 깊게 살펴보기

2.1 JSX란?

JSX는 트리구조로 표현하고 싶은 것을 JS로 쉽게 변환시키게 하기 위한 확장된 문법 구조라고 생각하면 좋다.

2.1.1 JSX의 정의

JSXElement

  • JSXOpeningElement: <JSXElement JSXAtrributes(optional)>
  • JSXClosingElement: <JSXElement/>
  • JSXSelfCLosingElement <JSXElement JSXAttributes(optional)/>
  • JSXFragment: <>JSXChildren(optional)</>

JSXElementName

  • JSXIdentifier: JSX내부에서 사용할 수 있는 식별자(js와 마찬자기로, 숫자로 시작하거나, $, _외의 특수문자는 불가능하다)
  • JSXNamespacedName: JSXIdentifier:JSXIdentifier의 조합, :로 묶을 수 있으며 1개만 묶을 수 있다.
  • JSXMemberExpression: JSXIdentifier.JSXIdentifier의 조합. .로 묶을 수 있으며 여러개가 사용 가능하고, JSXNamespacedName과 이어서 사용은 불가능하다.

JSXAttributes

  • JSXSpraedAttributes: {…AssignmentExpression}
  • JSXAttribute: 속성을 나타내는 키와 값

    • JSXAttributeValue: 속성의 키를 할당할 수 있는 값

      • JS와 같은 것: , 로 구성된 문자열, { AssignmentExpression }
      • JSXElement

JSXChildren

부모와 자식간의 관계를 만들어주는 가장 핵심적인 요소
  • JSXChild: JSXChildren을 이루는 단위, 이은 0개 이상을 가질 수 있음

    • JSXText: {, <, > ,} 를 제외한 문법
    • JSXElement
    • JSXFragment
    • { JSXChildExpression(optional) }

JSXString

  • JS 문자열과 같게 동작함(HTML과의 다른 점음 \ 의 처리 유무인데, 이는 JS로 동작한다.)

2.1.3JSX는 어떻게 자바스크립트에서 변환될까?

  • JSXElement를 첫 번째 인수로 선언해 요소를 정의
  • 옵셔널인 JSXChildren, JSXAttributes, JSXStrings는 이후 인수로 넘겨 처리

2.2. 가상 DOM과 리액트 파이버

2.2.1 DOM과 브라우저 렌더링 과정

HTML download, CSS, JS 다운로드 → 파싱이후 DOM, CSOOM생성 → 눈으로 보이는 부분 순회 → CSS를 대입 → layout, reflow → painting

2.2.2 가상 DOM의 탄생 배경

레이아웃 → repainting일 이러나 브라우저가 많은 소모를 사용하게 됨. 그래서 매번 그려주는 것보다 VDOM으로 미리 변할것을 계산하고 이를 DOM으로 대입해주는 것

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

리엑트 파이버는 다음과 같은 일을 한다.

  • 작업을 작은 단위로 분할하고 쪼갠 다음, 우선순위를 매긴다.
  • 이러한 작업을 일시 중지하고 나중에 다시 시작할 수 있다.
  • 이전에 했던 작업을 다시 재사용하거나 필요하지 않는 경우 폐기할 수 있다.

그렇다면 여기서 질문. JS는 single core 기반의 event loop인데(즉, 중단가능성이 없음) 어떻게 쪼개서 할 수 있지?

  • 리엑트는 작업 단위를 매우 잘게 쪼갠다.
  • 그리고 finishedWork(), commitWork()를 통해 변경하거나 저장한다.
얼마나 잘게 쪼갤까?

60fps 기준 1fps당 16ms

  • 주체: Scheduler
  • 방식: Time Slicing(5ms)
  • 시점: Fiber(작업 단위)와 Fiber 사이
  • 기준: shouldYield() (시간이 다 됐거나, 더 급한 일이 생겼는가?)
내부 속성들
  • tag: element와 1:1 관계를 가짐

    종류

    FunctionComponent, ClassComponent, IndeterminateComponent, HostRoot, HostPortal, HostComponent, HostText, Fragment, Mode, ContextCunsumer, ContextProvider, ForwardRef, Profiler, SuspenseComponent, MemoComponent, SimpleMemoComponent, LazyComponent, IncompleteClassComponent, DehydratedFragment, SuspenseListComponent, ScopeComponent, OffscreenComponent, LegacyHiddenComponent, CacheComponet, TracingMarkderComponent

  • stateNode: 파이버 자체의 참조(reference)
  • child, sibling, return: 파이버의 관계 개념
  • index: 형제들 사이에 자신이 몇번째인지
  • pendingProps: 작업을 미처 처리하지 못한 props
  • memoizedProps: pendingProps를 기준으로 렌더링이 완료된 이후에 pendingProps를 memoizedProps로 저장
  • updateQueue: 상태 업데이트
  • memoizedState: 함수 컴포넌트의 훅 목록
  • alternate: 리액트 파이버 트리

리엑트 파이버 트리

그래픽 쪽에서 사용하는 더블 버피링이라는 기술을 활용한다. 이는 다 그리지 못한 모습을 노출하지 않게 하기 위한 방식으로 current를 기준으로 workInProgress트리를 그리게 된다.

파이버의 작업 순서

  1. beginWork() 함수를 실행해 파이버 작업을 수행, 자식이 없는 파이버를 만날때까지 트리 형식으로 시작됨.
  2. completeWork() 함수를 실행해 파이버 작업을 완료
  3. 형제가 있다면 형제로 넘어가기
  4. return으로 돌아가 자신의 작업이 완료됨을 notifiy

2.2.4 파이버와 가상 DOM

가상 돔은 웹에서만 통용되는 개념이고, 파이버는 그래도 RN에서도 같이 된다. 즉 메커니즘이 리엑트의 핵심이다.