// 파이버 노드를 시작점으로 하여 루트 노드까지 이동하며
// 각 노드의 컴포넌트 함수 또는 클래스를 로그 출력
function traceReactParentsFromFiber(startingNode) {
  while (startingNode) {
    const componentFn = getComponentFn(startingNode);
    if (componentFn) {
      console.log(componentFn);
    }

    startingNode = startingNode.return;
  }
}

// 컴포넌트 함수 또는 클래스를 가져옴
function getComponentFn(node) {
  if (!node) return;

  if (typeof node.type === 'function') {
    return node.type;
  }

  if (node.type && typeof node.type.render === 'function') {
    return node.type.render;
  }
}

// 실제 실행 코드 (DOM 선택 가능, querySelector, 요소 선택 후 $0 가능)
// DOM 요소를 받아 해당 요소에 연결된 파이버 노드를 getFiberFromDOM 함수로 가져온 후
// 그 파이버 노드를 시작점으로 하여 상위 컴포넌트들을 로그 출력
function traceReactParentsFromDOM(domElement) {
  const fiberNode = getFiberFromDOM(domElement);
  traceReactParentsFromFiber(fiberNode);
}

// DOM 요소에서 연결된 파이버 노드를 가져옴
function getFiberFromDOM(domElement) {
  // DOM 요소의 프로퍼티 중 __reactFiber로 시작하는 키를 찾아 그 값 반환
  const fiberKey = Object.keys(domElement).find(key => key.startsWith('__reactFiber'));

  if (!fiberKey) return;

  return domElement[fiberKey];
}

// DOM 요소에서 연결된 파이버 노드의 프로퍼티를 반환
function getFiberPropsFromDOM(domElement) {
  const fiberKey = Object.keys(domElement).find(key => key.startsWith('__reactProps'));

  if (!fiberKey) return;

  return domElement[fiberKey];
}

 

사용방법

traceReactParentsFromDOM($0)
리액트에서 컴포넌트 렌더 스택 찾기