자신의 가상 DOM을 만들어서 이해하기 (2 섹션)

본고는 (그래서 첫 번째 부분도 읽는 것이 좋습니다:) 계속됩니다. 이 글에서 JSX와 유사한 함수인 하이퍼스크립트를 사용하여 가상 노드를 만들고 렌더링하는 방법을 배웠습니다.이 부분에서 우리는 가상 DOM의'차점'알고리즘을 실현할 것이다. 이것은 그의 주요 장점이다.
처음에 저는 2018년 인터넷 반란군 대회stefan judis의 강연 계발을 받았기 때문에 마음대로 보십시오here.
좋습니다. 동적 구성 요소를 렌더링하는 간단한 함수 구성 요소가 있습니다.자신의 상태를 도입하고render 방법을 사용하여 클래스로 변환하여 좀 복잡하게 만듭니다.이 밖에 우리는 새로운 인원 구성 요소를 분리할 수 있다. 이 구성 요소는 이모티콘 목록만 보여주는 것을 책임질 것이다.다음은 다음 상황입니다.
캐릭터 구성 요소, 속성에 지정된 표정 목록을 나타내는 데 사용
이 구성 요소는 특별한 점이 없습니다. 도구에 제시된 항목 목록만 보여 줍니다.주의: 우리는 여기서 렌더링 방법을 소개했다 — 실제로 실제 DOM을 렌더링하는 데 사용되는 가상 DOM을 생성합니다.다음은 응용 프로그램 구성 요소가 어떻게 변경되는지입니다.
App 구성 요소가class 구성 요소로 변경
여기서 두 가지를 언급해야 한다.
  • 우리는 그 구조 함수에 그 상태를 설정하고 타이머를 만듭니다. 이 타이머는 1초(1000ms)마다 그 상태를 업데이트합니다
  • 상태를 업데이트하기 위해 setState 방법을 사용합니다.
  • React’s documentation 에서 setState 방법이 무엇인지 찾을 수 있습니다.우리는 이곳에서 거의 같은 기능을 실현할 것이다 — 상태 객체를 업데이트하고 어셈블리를 다시 렌더링합니다.물론 React의 실현은 그리 간단하지 않다. 위에서 일련의 최적화를 진행했지만, 제발, 우리는 단지 그것을 구축하고 있을 뿐이다.)
    setState는 모든 함수를 호출하는 방법이기 때문에 이를 실현하는 추상적인 클래스를 만드는 것은 의미가 있습니다.클래스 MyApp extends를 작성할 때 반응합니다.React에서 클래스Component를 계승하고 있으며 그 방법을 사용할 수 있습니다.자, 처음부터 간단한 기본 구성 요소 클래스를 시작하겠습니다.
    기본 구성 요소 구현
    기본적으로, 우리는props와state 필드로 구성 요소를 초기화하고 setState 방법을 실현할 뿐, 이 방법은 기본적으로 우리의 상태를 다시 쓰고 그 매개 변수에서renderComponent를 호출합니다.이제 설명하지만 먼저 구성 요소를 변경합니다.
    우리 구성 요소의 변경 사항
    자, 이제 응용 프로그램과 인원 구성 요소를 업데이트했습니다. RenderComponent가 무엇을 해야 하는지 설명해 보겠습니다.
  • 이전 베이스(component.base에 저장된 변경 사항 이전의 현재 DOM)
  • 가상 DOM 구현 — 우리는 구성 요소에서 얻을 수 있다.렌더링 방법을 사용하여 어셈블리에 저장합니다.기초
  • 새 아이로 낡은 아이를 교체
  • 이것은 다음과 같습니다.
    renderComponent 함수 구현

    I’ve added parent parameter, to that we could use parent.appendChild when we render the root component first time.


    완벽한 작은 변경 사항은 렌더노드 함수를 조금 바꾸는 것입니다.옛날 모습 기억나?
    이전 렌더 노드
    DOM 요소만 처리하지만 실제로는 어플리케이션 구성 요소의 render\uu 메서드 ** 에 유사한 내용이 있습니다. _**
    return h('div', { class: 'app' },
     h('h1', null, 'Simple vDOM'),
     h(People)
     )
    
    보시다시피 노드 이름은 문자열 값을 얻을 수 있을 뿐만 아니라 다른 구성 요소/함수를 가져와 렌더링할 수 있습니다. 우리의 예시에서 이것이 바로 인간 구성 요소입니다.우리는 타당한 처리를 확보해야 한다 — 기본적으로 구성 요소를 초기화하고 렌더링하며 모든 하위 레벨에서 이 작업을 수행해야 합니다.다음은 우리가 업데이트한 renderNode 구현입니다.
    renderNode 함수 업데이트
    이게 렌더링!현재, 우리의 응용 프로그램은 완벽하게 실행되고 있다. 어떠한 상태 변경도 응용 프로그램을 다시 렌더링할 수 있다 — 따라서 각 하위 요소/어셈블리가 업데이트됩니다.이러한 방법을 활용하기 위해 응용 프로그램의 업데이트 작업을 응용 프로그램 구성 요소에서 인원 구성 요소로 이동합니다(응용 프로그램에서 구조 함수를 삭제하고 인원에서 작성합니다).
    인원 구성 요소의 구조 함수
    그리고 여기에서 인원의 렌더링 방법을 업데이트합니다: h('ul','null,...props.list.map(item=>h('li','null,item)))) 여기로 돌아가서 h('ul','null,...state.list.map(item=>h('li','null,item))
    이제 사용자 구성 요소가 상태가 업데이트될 때만 다시 렌더링됩니다.GIF 비교:
    어플리케이션을 다시 렌더링하기 전에
    애플리케이션
    보시다시피 목록만 업데이트되고 제목(단순 vDOM)은 다시 나타나지 않습니다.이제 우리는 우리의 구성 요소를 자치시켰다.

    Note 1 : I’ve changes a bit styles: displayed items in flex row, so that adding new items will not cause reflow.

    Note 2: To see which parts of the website re-render you can enable Paint flashing in Chrome Dev Tools -> More(… icon)-> More tools -> Rendering)


    차분 알고리즘


    응, 더 React-ish처럼 보이지만, 목록에 새 항목만 추가할 때, 전체 프로그램을 다시 보여주는 것은 엉망이야.이제'차점'알고리즘을 도입할 때입니다. 이것은 우리의 응용 프로그램을 더욱 강하게 할 것입니다.
    우리의 예에서, 우리는 새로운 가상 노드에 어떤 새로운 항목이 있는지 간단하게 검사할 수 있으며, 만약 있다면, 우리는 그것만 추가할 것이다.따라서 한 걸음 한 걸음 그것을 실시하자.먼저 DOM이 제공되지 않으면 가상 노드를 렌더링하여 상위 노드에 첨부해야 합니다.
    비교할 DOM이 없으면 응용 프로그램을 렌더링하여 상위 레벨에 추가합니다.
    이것은 첫 번째 실행에 적용됩니다 — _여기에는 DOM 렌더링이 없으며 매개변수에서 _parent를 제공하는 유일한 곳입니다.따라서 초기 렌더링에 사용할 수 있으며 다음을 수행하는 방법은 다음과 같습니다.
    첫 렌더링 어플리케이션
    자, 이제 응용 프로그램을 보여 줍니다. 캐릭터 구성 요소는 1초 후에 상태를 업데이트합니다. (우리가 설정한 타이머를 기억하십니까?)그러면 renderComponent가 호출되므로 다음과 같이 변경됩니다.
    업데이트된 renderComponent
    먼저 구성 요소를 사용하여 가상 DOM을 만듭니다.render 방법, 그리고 현재 DOM 상태 (component.base 필드에 저장) 와 비교하고 diff 결과를 다시 저장합니다.그래서 우리의diff 함수는 새로운 하위 항목이 있는지 확인해야 한다. 만약 사실이라면, 우리는 그것을 추가하기만 하면 된다.다음은 모양입니다.
    새 아이의 간단한 차이점 검사
    그렇습니다. 우리는 성공했습니다!이제 세 번째 교체에서의 모습을 살펴보자.
    확산 알고리즘을 사용하여 렌더링
    보시다시피 전체 응용 프로그램과 목록은 다시 렌더링되지 않습니다.새 하위 항목만 목록에 추가됩니다.
    이것은 단지 간단한 예일 뿐, 간단한'차점'알고리즘을 가지고 있지만, 이러한 개념에 익숙하지 않은 사람들에게 의미가 있기를 바란다.React와 비교할 수 없습니다.다음은 React’s diffing 알고리즘의 일부입니다.
  • 비교 유형
  • 비교 속성(아이템)
  • 아이 비교
  • 물론 엔진 덮개 아래에 대량의 최적화가 있어 React가 이렇게 강력하고 아름다운 UI 라이브러리를 만들 수 있다.

    If you liked this and posts feel free to like(❤) and "unicorn" it, that will motivate me to do stuff like this more. Thanks for reading!

    UPDATE 24.11.2019: If you want to learn React by doing many exercises, feel free to sign up to my upcoming course 30-day-React.


    리소스:
  • Stefan Judis: What the v…DOM? | Web Rebels 2018
  • Implementation of this experiment by Stefan Judis in CodePen
  • GitHub repo of this experiment
  • React’s diffing algorithm
  • 좋은 웹페이지 즐겨찾기