수천 단어의 기사는 React가 무엇인지, React가 무엇을 가지고 있는지, React를 사용하는 방법을 이해하는 데 도움이 될 것입니다. (하나)

수명주기

생애주기란 무엇인가

한 문장으로 말하면 생성부터 소멸까지의 과정이 생명주기이다.

그렇다면 반응 수명주기의 단계는 무엇입니까?

  1. 초기화 단계
    constructor 생성자
    getDefaultProps 소품 기본값
    getInitialState 상태 기본값
  2. 마운트 단계
    componentWillMount 구성요소 초기화 및 렌더링 전에 호출됨
    render 구성요소 렌더링
    componentDidMount 구성요소가 DOM에 마운트된 후 호출됨< /span>
  3. 업데이트 단계
    componentWillReceiveProps 구성 요소가 새 prop을 받기 전에 호출됩니다.
    shouldComponentUpdate 구성 요소를 업데이트해야 하는지 여부
    componentWillUpdate 호출됩니다. 구성 요소가 업데이트되기 전< /span> 구성 요소 업데이트 후 호출됨
    render 구성 요소 렌더링
    componentDidUpdate
  4. 하역 단계
    componentWillUnmount

React16의 새로운 라이프 사이클에서는 세 가지 메소드인 componentWillMount, componentWillReceiveProps, componentWillUpdate가 더 이상 사용되지 않으며 가 추가되었습니다. a>) 이 세 가지 후크는 React16에서 삭제되지 않았습니다. 그러나 혼합할 수는 없습니다. 새로운 후크 기능. React17은 이 세 가지 후크 기능을 삭제하고 새로운 오류 처리 기능을 추가합니다( 더 이상 사용되지 않는 세 가지 후크 기능을 대체합니다. getDerivedStateFromProps, getSnapshotBeforeUpdate
componentDidCatch

그렇다면 새로운 방법을 사용하는 방법은 무엇입니까?

getDerivedStateFromProps: 구성 요소가 빌드된 후(가상 돔 이후, 실제 DOM이 마운트되기 전)를 포함하여 구성 요소가 다시 렌더링될 때마다, 새로운 props 또는 상태를 얻은 후 매번 반환됩니다. 새 prop을 수신합니다. 객체가 새 상태 역할을 합니다. null을 반환한다는 것은 상태를 업데이트할 필요가 없음을 의미합니다. componentDidUpdate을 사용하면 componentWillReceiveProps.

getSnapshotBeforeUpdate: 트리거 시간: 업데이트가 발생할 때, 렌더링 후 및 컴포넌트 DOM 렌더링 전; componentDidUpdate의 세 번째 매개변수로 값을 반환; < a i=2>와 협력 , 의 모든 사용법을 다룰 수 있습니다. componentDidUpdatecomponentWillUpdate

componentDidCatch: 수명 주기 메서드나 하위 구성 요소의 렌더링 단계 중에 오류가 발생하면 componentDidCatch() 메서드가 호출됩니다. 이 방법은 React 애플리케이션의 오류 경계를 구현하는 데 사용됩니다. 커밋 단계에서 호출되므로 렌더링 단계에서 호출되는 getDerivedStateFromError()와 달리 이 메서드에서는 side-effects을 사용할 수 있습니다. 이 방법은 오류를 기록하는 데에도 사용됩니다. errorinfo; error라는 두 개의 매개변수를 받습니다. 이는 하위 구성 요소에서 발생하는 오류입니다. info: componentStack이 오류를 일으킨 구성 요소에 대한 추적을 저장합니다.

부작용

  • 먼저 설명纯函数(Pure function): 함수에 동일한 매개변수를 주면 항상 같은 값이 반환되며 부작용도 없습니다. 이 개념을 React에 적용하면 함수를 제공한다는 의미입니다. < a i=2> 동일, 항상 동일한 뷰를 렌더링하고 다른 부작용이 없습니다. 순수 구성 요소의 장점은 데이터 변경 사항을 쉽게 모니터링할 수 있다는 것입니다. 테스트, 렌더링 성능 개선 등을 위해; a>Pure componentprops

  • 부작용(Side Effect)은 전역 변수 수정, 전달된 매개변수 수정 등 자체 작업의 반환 값과 관련이 없는 작업을 수행하는 함수를 나타냅니다. 은 부작용으로 간주됩니다. 작업 및 수정 console.log()라도 ajaxdom

가상돔

가상 돔의 정의

이는 본질적으로 DOM에 대한 보다 가벼운 설명인 JS 객체입니다.

React는 DOM 운영의 문제점, 즉 항상 페이지 전체를 새로 고치는 문제를 해결하기 위해 새로운 아이디어를 제시합니다. 전후 상태 변경이 발생하면 React는 자동으로 UI를 업데이트하지만 단점은 매우 까다롭다는 것입니다. 느린. 따라서 변경되지 않은 DOM 노드는 그대로 두고 변경된 DOM 노드만 생성 및 교체하여 노드 재사용을 달성하므로 문제는 두 DOM 노드 간의 차이점을 어떻게 비교하는가로 변환됩니다. DOM은 트리 분해이기 때문에 완성된 트리 구조 비교 알고리즘의 복잡도는 O(n^3)입니다.

React는 복잡성을 줄이기 위해 세 가지 최적화를 수행했습니다.
  1. 상위 노드가 다른 경우 하위 노드 비교를 중단하고 기존 노드를 직접 삭제한 후 새 노드를 추가하여 다시 렌더링합니다.
  2. 자식 노드가 변경되면 VirtualDOM은 변경 사항을 계산하지 않고 두 번 다시 렌더링합니다.
  3. 고유한 키 값을 설정하여 노드를 비교합니다. 실제 DOM에는 많은 속성이 있으며 그 중 대부분은 DIff에 사용되지 않으므로 더 가벼운 JS 객체를 사용하여 복잡한 DOM 노드를 대체하면 많은 수의 쿼리 작업을 피할 수 있습니다. DOM에.

가상 돔의 역할

  1. 일부 성능을 희생시키면서 유지 관리성이 향상됩니다.
  2. 프레임워크를 크로스 플랫폼으로 만들 수 있습니다.
  3. 높은 수준의 구성 요소 추상화

가상 돔의 단점

  1. 처음으로 많은 양의 DOM을 렌더링하는 경우 가상 DOM의 여러 레이어 계산으로 인해 약간 느려집니다.
  2. 메모리에 DOM 사본을 유지해야 함
  3. 이는 가상 DOM이 크게 변경되는 경우에 적합합니다. 그러나 한 번만 자주 업데이트하는 경우 가상 DOM은 계산을 처리하는 데 더 많은 시간을 소비합니다. 따라서 상대적으로 페이지 수가 적은 DOM 노드가 있는 경우 실제로 가상 DOM을 사용하면 속도가 느려질 수 있습니다.

setState메커니즘

setState동기식인가요, 비동기식인가요?

React의 라이프 사이클과 합성 이벤트에서 React는 여전히 업데이트 메커니즘에 있습니다. 몇 번 호출되더라도setState 업데이트가 즉시 수행되지는 않지만, 업데이트된 값은 _pendingStateQueue에 저장되고, 업데이트할 구성 요소는 dirtyComponent에 저장됩니다.
마지막 업데이트 메커니즘이 완료되면 라이프 사이클을 예로 들어 모든 구성 요소, 즉 최상위 구성 요소 didmount가 배치 플래그를 설정합니다. 거짓으로. 이때 dirtyComponent의 구성 요소와 _pendingStateQueue의 상태가 제거되어 업데이트됩니다. 이렇게 하면 구성 요소가 여러 번 다시 렌더링되지 않습니다.

componentDidMount() {
    
    
	this.setState({
    
    
		index: this.state.index + 1
	})
	console.log('state', this.state.index);
}

따라서 위의 코드처럼 실행 직후 setState 받으면 업데이트된 버전을 얻을 수 없습니다. a>< a i=3>, React의 일괄 처리 메커니즘에 있기 때문에 는 임시로 저장되며, 일괄 처리 메커니즘이 완료된 후 균일하게 업데이트됩니다. 그래서요. 자체는 비동기식이 아니지만 React의 일괄 처리 메커니즘은 비동기성의 환상을 제공합니다. statestatestate
setState

비동기 코드 및 기본 이벤트에서:

componentDidMount() {
    
    
	setTimeout(() => {
    
    
		console.log('调用setState');
		this.setState({
    
    
			index: this.state.index + 1
		})
	console.log('state', this.state.index);
	}, 0);
}

위 코드와 같이 비동기 코드에서setState 호출하면 JavaScript의 비동기 메커니즘에 따라 비동기 코드가 먼저 일시적으로 저장되고 결국 처리됩니다. 동기 코드가 실행됩니다. 실행됩니다. 이때 React의 일괄 처리 메커니즘이 완료되었으며 처리 플래그가 false로 설정되었습니다. 이때 setState을 호출합니다. 다시 업데이트를 즉시 실행하고 업데이트된 결과를 얻으려면
기본 이벤트에서 setState 호출은 React의 일괄 처리 메커니즘을 트리거하지 않으므로 즉시 최신 결과를 얻을 수 있습니다.

모범 사례
setState 의 두 번째 매개변수는 React의 일괄 처리 메커니즘이 완료된 후 호출될 함수를 수신하므로 setState를 호출하려고 합니다. 즉시 업데이트된 값을 이 콜백 함수에서 가져오세요

  • setState새로운 지위를 얻다
  • 수신된 새 상태는 즉시 실행되지 않고pendingStates(대기 대기열)에 저장됩니다.

setState실행원리

두 가지 범주로 나눌 수 있습니다:

  1. 일괄 업데이트 클래스: 즉, react의 내부 실행 기능과 setState의 실행 로직은 다음을 포함하는 일괄 업데이트 처리입니다. 내부 이벤트 반응 (합성 이벤트) 및 수명주기
  2. 비배치 업데이트 유형: 위의 두 가지 상황 이외의 상황, 흔히 볼 수 있는 상황: 네이티브 이벤트, setTimeout, fetch 등;< / 아>

두 가지 개념:

  1. 트랜잭션(Transaction): 일반적인 기능이 다른 레이어에 래핑되어 있다는 것을 이해할 수 있습니다. 이 패키지 처리 계층에는 함수 실행 전의 하나 이상의 처리 기능(초기화 기능)과 기능 실행 후의 하나 이상의 처리 기능(닫기 기능)이 포함됩니다. React의 많은 논리적 처리는 트랜잭션 개념을 사용합니다.
  2. 합성 이벤트와 기본 이벤트의 관계 및 차이점:
    차이점: 기본 이벤트는 addEventListener 방식으로 작성된 이벤트입니다! 합성 이벤트는 React에서 onClick, onChange 등을 직접 작성하는 것이며,
    관계: 합성 이벤트는 기본 이벤트를 래핑하는 것으로 이해될 수 있지만 기본 이벤트는 는 위의 트랜잭션 개념의 일반 기능과 동일하며, 패키징 처리 이후에 형성된 트랜잭션은 반응의 합성 이벤트입니다.

네이티브 이벤트에서setStaterender 업데이트를 직접 트리거하므로 네이티브 이벤트에서 예제의 실행 순서는 첫 번째입니다. a>render다음 실행callback,setState트랜잭션이 실행된 후 인쇄가 실행됩니다. 인쇄되는 것은 setState 등의 업데이트 이후 상태이므로 위의 기본 이벤트의 인쇄 순서가 나타나는데 이는 매우 명확합니다.

이것은 합성 이벤트의 경우가 아닙니다. 트랜잭션 1을 직접 시작하고 함수가 실행되기 전에 일괄적으로 상태 업데이트를 시작합니다(isBatchedUpdates is true, 기본값은 < /span>. 업데이트는 대신 지금은 실행되지 않습니다. 를 실행하는데, 이때 일괄 업데이트 상태가 됩니다. , false!), ON 후 합성 이벤트에서 setStatesetStaterenderstatecallback

일괄 업데이트는 기본적으로 꺼져 있으며, 이후 바로 실행됩니다batchedUpdates(이 기능은 업데이트 렌더링 기능입니다). 일괄 업데이트 상태가 활성화되었는지 여부는 다음과 같습니다. 일괄 업데이트가 활성화되면 상태 push가 배열(dirtyComponents)에 추가됩니다.

상태를 수집한 후 트랜잭션을 실행하는 close 함수는 무엇을 합니까? 하나는 일괄 업데이트 상태를 닫는 것이고, 다른 하나는 수집된 상태의 처리를 공식적으로 시작하는 것입니다. 여기서 새로운 트랜잭션이 열립니다: 트랜잭션 2. 트랜잭션 2는 복잡한 처리 후 수집된 상태, 즉 dirtyComponents를 업데이트합니다. 처리 후에는 트랜잭션 2의 close 기능이 실행되어 전체 업데이트된 상태를 재설정합니다. 이 함수는 여기 트랜잭션 1에서도 수집됩니다. callback; ;a>

总结 setState:

  1. setState실행은 두 가지 주요 범주로 나뉩니다: 하나는 수명 주기 및 합성 기능이고, 다른 하나는 이전이 아닌 두 가지 상황입니다.
  2. 두 유형 setState 모두 동기적으로 실행되지만 일괄 업데이트 클래스에서는 statecallback이 수집됩니다. 지연 처리되며 이는 데이터의 비동기 실행으로 이해될 수 있으며 일괄 업데이트 클래스의 setState 대신 업데이트 렌더링을 직접 트리거합니다.
  3. callbackstate 은 동시에 수집되며, render 이후에는 균일하게 처리됩니다.

합성 이벤트 메커니즘 및 원리

fiber 메커니즘의 특성으로 인해 파이버 노드가 생성될 때 해당 dom 노드가 아직 마운트되지 않을 수 있습니다. < i=3>과 같은 이벤트 처리 함수는 노드의 로 사용되므로 실제 DOM 노드에 직접 바인딩할 수 없습니다. 이를 위해 React는 "최상위 등록, 이벤트 수집, 통합 트리거"라는 이벤트 메커니즘을 제공합니다. onClickfiberprop

소위 "최상위 등록"은 실제로 통합 이벤트 처리를 root 요소 기능. "이벤트 수집"은 이벤트가 발생하는 시점(실제로는 root의 이벤트 처리 기능이 실행되는 시점)을 의미하며, 합성 이벤트 개체를 생성하고 버블링 또는 캡처 경로를 따라 구성 요소에서 실제 이벤트 처리 기능을 수집합니다. "통합 트리거"는 수집 프로세스 이후에 발생하며, 수집된 이벤트는 하나씩 실행되며 동일한 합성 이벤트 개체를 공유합니다. 여기서 중요한 점은 root 에 바인딩된 이벤트 리스너가 우리가 컴포넌트에 작성한 이벤트 처리 함수가 아니라는 점입니다. 아래에서 설명할 이 차이점에 주의하세요.

위는 React 이벤트 메커니즘에 대한 간략한 설명입니다. 이 메커니즘은 이벤트를 DOM 노드에 직접 바인딩할 수 없는 문제를 방지하고fiber 이벤트 실행 경로를 생성하여 이벤트 캡처 및 버블링을 시뮬레이션하고 두 가지 매우 중요한 기능을 제공합니다.

이벤트 분류에는 이벤트로 생성된 작업에 대한 다양한 우선순위가 포함될 수 있습니다.

브라우저 호환성 차이를 완화하기 위해 합성 이벤트 객체 제공

다음으로, 이벤트 등록부터 실행까지 이벤트의 라이프사이클 전반에 걸쳐 이벤트 메커니즘을 자세히 설명합니다.

  1. 이벤트 처리 기능은 컴포넌트의 요소에 바인딩되지 않고 루트에 바인딩되는데 이는 파이버 트리의 구조적 특성과 관련이 있습니다. 즉, 이벤트 처리 기능은 파이버의 소품으로만 사용할 수 있습니다.
  2. 루트에 바인딩된 이벤트 리스너는 우리가 컴포넌트에 작성한 이벤트 핸들러 함수가 아니라 이벤트 우선순위를 보유하고 이벤트 실행 단계 플래그를 전달할 수 있는 리스너입니다.

합성 이벤트 객체

컴포넌트의 이벤트 처리 기능에서 얻은 이벤트 객체는 네이티브 이벤트 객체가 아니고 React로 합성한 객체입니다SyntheticEvent. 다양한 브라우저 간의 호환성 차이를 해결합니다. 개발자의 정신적 부담을 덜어주기 위해 통합된 이벤트 개체로 추상화합니다.

섬유

동시 계산 작업이 너무 많아 브라우저의 UI 렌더링이 차단됩니다. 기본적으로 JS 작업, 페이지 레이아웃 및 페이지 그리기는 모두 브라우저의 기본 스레드에서 실행되며 상호 배타적입니다. JS 작업이 계속해서 메인 스레드를 차지하면 페이지가 제때 업데이트되지 않습니다. 페이지를 업데이트하기 위해 setState을 호출하면 React는 애플리케이션의 모든 노드를 순회하고 차이점을 계산한 다음 UI를 업데이트합니다. 전체 프로세스는 한 번에 완료되며 중단될 수 없습니다. 페이지 요소가 많은 경우 전체 프로세스에 16밀리초 이상이 소요될 수 있으며 프레임 드롭이 쉽게 발생할 수 있습니다.

JS 작업이 오랫동안 메인 스레드를 점유하는 문제를 해결하기 위한 기본 아이디어는 작업을 여러 단계로 나누어 일괄적으로 완료하는 것입니다. 즉, 작업의 일부를 완료한 후 제어권이 브라우저로 반환되어 브라우저가 페이지를 렌더링할 시간을 허용합니다. 브라우저가 완료될 때까지 기다린 다음 완료되지 않은 작업을 계속합니다.

window.requestIdleCallback()브라우저가 유휴 상태일 때 함수가 순차적으로 호출되므로 개발자는 지연되었지만 애니메이션 및 사용자 상호 작용과 같은 중요한 이벤트에 영향을 주지 않고 기본 이벤트 루프에서 백그라운드 또는 우선 순위가 낮은 작업을 수행할 수 있습니다. 브라우저가 함수를 호출하기 전에 함수의 제한 시간이 만료되지 않는 한 함수는 일반적으로 선입선출 순서로 실행됩니다.

React 프레임워크의 내부 작업은 3개의 레이어로 나눌 수 있습니다.

  • 페이지의 모양을 설명하는 가상 DOM 레이어.
  • Reconciler 계층은 구성 요소 수명 주기 메서드 호출, Diff 작업 수행 등을 담당합니다.
  • 렌더러 레이어는 다양한 플랫폼에 따라 해당 페이지를 렌더링하는데, 가장 일반적인 것은 ReactDOM과 ReactNative입니다.

react16 이후 버전에서 가장 큰 변화는 의심할 여지 없이 Reconciler 레이어입니다. React 팀에서는 Fiber Reconciler라는 새로운 이름도 부여했습니다.
Fiber Reconciler의 실행 과정은 2단계로 나누어집니다.

  • 첫 번째 단계에서는 Fiber 트리가 생성되고 업데이트해야 할 노드 정보를 얻습니다. 이 단계는 점진적인 프로세스이므로 중단될 수 있습니다.
  • 두 번째 단계에서는 업데이트가 필요한 노드가 일괄 업데이트되며 이 프로세스는 중단될 수 없습니다.

1단계의 인터럽트 가능 기능을 사용하면 우선순위가 더 높은 작업을 먼저 실행할 수 있으므로 프레임워크 수준에서 페이지 프레임이 삭제될 확률이 크게 줄어듭니다.
Fiber Reconciler가 1단계에서 Diff 계산을 수행하면 Fiber 트리가 생성됩니다. 이 트리는 Virtual DOM 트리를 기반으로 추가적인 정보를 추가하여 생성된 것으로 본질적으로 연결리스트(linked list)이다.
Fiber 트리는 처음 렌더링할 때 한 번에 생성됩니다. 나중에 Diff가 필요할 때 기존 트리와 최신 Virtual DOM 정보를 기반으로 새 트리가 생성됩니다. 이 새 트리에 새 노드가 생성될 때마다 실행해야 할 우선순위가 더 높은 작업이 있는지 확인하기 위해 제어가 메인 스레드로 반환됩니다. 그렇지 않다면 트리를 만드는 과정을 계속하세요.
프로세스 중에 수행해야 하는 우선순위가 더 높은 작업이 있는 경우 Fiber Reconciler는 생성 중인 트리를 삭제하고 유휴 상태일 때 다시 실행합니다.
Fiber 트리를 구성하는 과정에서 Fiber Reconciler는 업데이트해야 할 노드 정보를 Effect List에 저장하게 되며, 2단계가 실행되면 해당 노드가 일괄적으로 업데이트됩니다.

Fiber는 어떻게 구현되나요?

链表、一次Fiber循环所有节点访问两次、requestIdleCallback

Fiber에 대한 깊은 이해

필요
1. 每一个状态的改变不是都需要马上反应在UI界面上
2. 不同的状态改变应该有不同的优先级,如动画,输入等应该有更高的优先级
3. 对于大量状态的改变复杂操作应该进行更好的调度,避免UI页面卡顿
섬유구조

파이버 트리의 전체 구조는 양방향 순환 연결 리스트로, 이 구조를 사용하면 해당 노드를 더 빨리 찾을 수 있습니다.
Reconcile 과정에서 이전 노드의 정보를 알기 위해서는 새로운 Fiber 노드가 기존 Fiber 노드와 연결되어야 합니다.
Fiber에는 동시에 두 개의 Fiber Tree가 있습니다. 각 Reconcile의 과정은 새로운 Fiber Tree를 구축하는 과정입니다. Commit 후에는 새로운 Fiber Tree가 현재 Fiber Tree가 됩니다. 등등. .

섬유 효과

조정 프로세스 중에 노드는 이전 노드와 비교되어야 하는 상태로 설정되어야 합니다. 각 Fiber 노드가 구성된 후(자체 effectTag 상태 설정) 효과가 있는 경우 자체 및 하위 요소를 상위 노드의 효과에 넣습니다. 이러한 방식으로 레이어별로 모든 효과가 저장됩니다. 새 파이버 트리에서 처리할 파이버 노드입니다. 그런 다음 커밋 단계에 들어가 모든 파이버 노드를 DOM으로 변환하고 UI 페이지를 새로 고칩니다.

파이버 스케줄링

Fiber는 가상 스택이므로 예약이 필요합니다. 페이지 렌더링을 차단하지 않도록 브라우저가 유휴 상태일 때 이 함수를 사용하여 코드를 실행할 수 있습니다.

섬유 우선순위

더 나은 사용자 경험을 위해서는 애니메이션, 입력 등 우선순위가 높은 작업을 먼저 실행해야 합니다. Fiber에는 5가지 우선순위가 있으며 각 우선순위는 만료 시간에 해당합니다.
일반인의 관점에서 시간 분할은 작업을 여러 유형으로 나누는 것을 의미합니다. 특히:

  1. 즉시 수행해야 하는 작업
  2. 사용자가 활동하지 않는 동안 수행해야 하는 작업
  3. 일반적인 작업
  4. 우선순위가 낮은 작업
  5. 브라우저가 유휴 상태일 때 수행되는 작업

우선순위에 따라 실행합니다. 새 작업이 삽입되면 우선순위에 따라 재정렬됩니다.
이 모듈은 두 개의 새로운 es6 API, 즉 a를 사용하여 구현됩니다. >window.requestAnimationFramewindow.requestIdleCallback. 구체적인 사용법은MDN에서 확인할 수 있습니다. 각 주기마다 만료된 작업이 있으면 만료된 작업을 무슨 일이 있어도 실행해야 하며, 남은 시간이 있으면 만료 시간이 더 짧은 작업이 먼저 실행되는 식입니다.

추천

출처blog.csdn.net/zw7518/article/details/124469084