React 에서 useEffect 와 useLayoutEffect 의 차이

선행 지식
우 리 는 React 의 작업 절 차 를 몇 개의 큰 덩어리 로 나 눌 수 있다.
  • render 단계:Fiber 노드 를 생 성하 고 완전한 Fiber 트 리 를 구축 합 니 다
  • commt 단계:이전 render 단계 에서 rootFiber 에 부작용 링크 를 생 성하 고 응용 DOM 작업 은 이 단계 에서 실 행 됩 니 다
  • commt 단계 의 작업 은 주로 세 부분 으로 나 뉘 는데 원본 코드 에 대응 하 는 함수 이름 은:
  • commtBeforeMutation Effects 단계:DOM 작업 을 수행 하기 전의 관련 작업 을 주로 처리 합 니 다
  • commtMutationEffects 단계:DOM 작업 수행
  • commtLayoutEffects 단계:DOM 작업 을 수행 한 후의 관련 작업 을 주로 처리 합 니 다
  • useEffect 와 useLayout Effect 의 차 이 는 주로 이 세 단계 의 처리 에 나타난다.결론 은 useEffect 는 응답 함수 와 지난번 소각 함 수 를 비동기 적 으로 실행 하고 useLayout Effect 는 응답 함수 와 지난번 소각 함 수 를 동기 적 으로 실행 합 니 다.즉,DOM 렌 더 링 을 막 습 니 다.
    useEffect
    commitBeforeMutationEffects
    이 단계 에서 useEffect 는 다음 과 같은 한 마디 를 겪 습 니 다.
    
    function commitBeforeMutationEffects() {
      while (nextEffect$1 !== null) {
        //           ,   flags     FunctionComponent effect flags,        
        var flags = effect.flags;
    
      //       
        if ((flags & Snapshot) !== NoFlags) {
          setCurrentFiber(nextEffect$1);
          commitBeforeMutationLifeCycles(current, nextEffect$1);
          resetCurrentFiber();
        }
    
     //   if     useEffect   true,useLayoutEffect  false
        if ((flags & Passive) !== NoFlags) {
          // If there are passive effects, schedule a callback to flush at
          // the earliest opportunity.
          if (!rootDoesHavePassiveEffects) {
            rootDoesHavePassiveEffects = true;
     //      useEffect      ,DOM   React    flushPassiveEffects
            scheduleCallback(NormalPriority, function () {
              flushPassiveEffects();
              return null;
            });
          }
        }
    
        nextEffect$1 = nextEffect$1.nextEffect;
      }
    }
    
    
    commitMutationEffects
    이 단계 에서 React 는 일련의 DOM 노드 업 데 이 트 를 한 다음 에 하나의 방법 을 실행 합 니 다.commt Hook EffectList Unmount(Hook Layout|Hook HasEffect,finished Work);
    그러면 useEffect 를 가 진 Functional Component 는 이 단계 에서 unmount 의 판단 논리 에 부합 되 지 않 기 때문에 이곳 에서 unmount 작업 을 하지 않 습 니 다.
    commitLayoutEffects
    이 단계 에서 중요 한 방법 이 존재 합 니 다.commt Hook Effect ListMount(Hook Layout|Hook HasEffect,finished Work);
    이 if 판단 은 이전 단계 의 if 판단 과 같 으 며,useEffec 는 이 판단 에서 어떠한 조작 도 하지 않 습 니 다.
    후속 단계
    commtLayout Effects 를 완성 한 후 다음 작업 이 있 습 니 다.
    
    if (rootDoesHavePassiveEffects) {
        // This commit has passive effects. Stash a reference to them. But don't
        // schedule a callback until after flushing layout work.
        rootDoesHavePassiveEffects = false;
        rootWithPendingPassiveEffects = root;
        pendingPassiveEffectsLanes = lanes;
        pendingPassiveEffectsRenderPriority = renderPriorityLevel;
      }
    
    
    즉,root With Pending PassiveEffects 를 root 로 설정 합 니 다.이렇게 하 는 이 유 는 1 단계 commt BeforeMutation Effects 에서 useEffect 가 등 록 된 다음 flush PassiveEffects 의 보조 와 관련 이 있 습 니 다.다음 flush PassiveEffects 의 실현 을 살 펴 보 겠 습 니 다.
    
    function flushPassiveEffectsImpl() {
     if (rootWithPendingPassiveEffects === null) {
        return false;
      }
     //              
     commitPassiveUnmountEffects(root.current);
      commitPassiveMountEffects(root, root.current);
    }
    
    
    
    상기 코드 세그먼트 에서 볼 수 있 듯 이 useEffect 가 1 단계 에 등 록 된 스케줄 링 리 셋 은 페이지 업데이트 후 unmount 와 mount 작업 을 합 니 다.특히 이 리 셋 에서 effect 의 등록 시 기 는 commt Layout Effects 단계 에 있다.
    useLayoutEffect
    사실 우리 가 useEffect 에 대한 분석 을 보면 commt Mutation Effects 와 commt Layout Effects 단계 에서 각자 의 if 판단 에서 useLayout Effect 는 if 를 통 해 판단 되 기 때문에 commt Mutation Effects 단계 에서 useLayout Effect 의 지난번 소각 함 수 를 동시에 실 행 했 습 니 다.commt Layout Effects 단계 에서useLayout Effect 의 이번 실행 함 수 를 동기 화하 고 소각 함 수 를 등록 합 니 다.
    결론.
    이로써 우 리 는 commt 단계 의 코드 를 대충 살 펴 보고 useEffect 가 왜 비동기 적 으로 실행 되 는 지 분 석 했 습 니 다.useLayout Effect 는 동기 적 으로 실 행 됩 니 다.구체 적 인 코드 는 글 에 너무 붙 이지 않 았 습 니 다.이것 은 모두 가 변 적 이기 때 문 입 니 다.진정한 절차 적 개관 과 React 팀 이 이 메커니즘 을 설계 하 는 심리 모델 은 우리 스스로 가 끊임없이 코드 를 디 버 깅 하고 이해 하 는 과정 에서 천천히 익 혀 야 한다.
    후속 적 으로 자신 이 관심 을 가 지 는 것 은 hooks 의 실현 이다.그 중에서 비교적 관건 적 인 useReducer 는 소스 코드 를 중심 으로 간단 한 버 전 을 써 서 알 리 페 이 애플 리 케 이 션 에 넣 어서 사용자 정의 알 리 페 이 hooks 를 일상 생산력 개발 에 사용 할 수 있 는 지 살 펴 볼 것 이다.
    React 에서 useEffect 와 useLayoutEffect 의 차이 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 React useEffect useLayoutEffect 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부탁드립니다!

    좋은 웹페이지 즐겨찾기