
Codefug Blog

react-dev-tools 정리, 실습
react-dev-tools
React 팀이 만든 React 앱 개발 도구입니다.


React 개발자 도구를 다운로드하면 두 가지 탭이 추가됩니다.
Component와 Profiler입니다.
Component 탭에서는 React 앱의 컴포넌트 트리를 확인할 수 있습니다.
props, hooks 등 다양한 정보를 확인할 수 있습니다.

개발자 도구처럼 Hover 시 해당 컴포넌트의 정보를 확인할 수 있습니다.


React 앱은 트리 구조로 되어 있습니다.
React 개발자 도구에서 트리를 확인할 수 있습니다.
Anonymous 노드는 익명 컴포넌트를 의미합니다.
함수 선언식이나 함수 표현식으로 생성한 컴포넌트는 함수명을 표시합니다.
그렇지 않은 경우 다음 로직을 따릅니다.
_default로 처리됩니다. (16.8 기준, 16.9부터는 임의의 값으로 추론)16.9부터 일부 개선되었지만 _c5 같은 임의의 값이므로 기명 함수를 사용하는 것이 좋습니다.
displayName을 적용하는 방법도 있습니다.
고차 컴포넌트에 특히 유용합니다. displayName을 동적으로 설정할 수 있습니다.
function withHigherOrderComponent(WrappedComponent) {
class WithHigherOrderComponent extends React.Component {}
WithHigherOrderComponent.dissplayName = `WithHigherOrderComponent(${getDisplayName(WrappedComponent)})`;
return WithHigherOrderComponent;
}
function getDisplayName(WrappedddComponent) {
return WrappedComponent.displayName || WrappedComponent.name || "Component";
}
래핑된 컴포넌트의 displayName, name, 또는 'Component'를 반환하여 고차 컴포넌트에 설정할 수 있습니다.
래핑된 컴포넌트와 고차 컴포넌트를 구분할 수 있어 개발 모드에서 편리합니다.
terser 같은 압축 도구가 컴포넌트명을 난수화할 수 있습니다.
Component.displayName은 빌드 도구가 삭제할 수 있으므로 개발 모드에서만 사용하는 것이 좋습니다.

컴포넌트를 선택하면 해당 컴포넌트의 자세한 정보를 보여줍니다.

컴포넌트들을 mapping으로 구현한 부분입니다.
key 값이 표시되어 있습니다.
React에서 key 값은 props로 전달되지 않으며 Fiber 트리에서 비교용으로만 사용됩니다.
하지만 개발자 도구에는 표시됩니다.
Anonymous 컴포넌트명과 각 부분의 key 값을 확인할 수 있습니다.
Anonymous가 빨간색인 이유는 strict mode로 렌더링되지 않았기 때문입니다.

props 부분 오른쪽에 세 개의 아이콘이 있습니다.

해당 컴포넌트가 DOM element에서 어떻게 렌더링되었는지 확인합니다.


콘솔 창에 해당 컴포넌트의 정보를 출력합니다.

해당 컴포넌트의 props, hooks, nodes를 볼 수 있습니다.

해당 컴포넌트의 소스코드를 확인할 수 있습니다.

프로덕션 모드에서 빌드된 소스코드는 최대로 압축되어 있습니다.
{} 버튼을 누르면 읽기 쉬운 형태로 표시됩니다.


props의 값을 클립보드에 복사한다.
window.$r에 해당 정보를 저장합니다.

복사한 내용을 임의의 변수명($reactTemp0)에 저장하여 콘솔에서 사용할 수 있습니다.

값이 함수인 경우 소스코드로 이동하는 Go to definition이 있습니다.

해당 함수의 소스코드로 이동합니다.
사용 중인 훅 정보를 확인할 수 있습니다.

State, Reducer, Context, Memo, Callback, Ref, id, LayoutEffect, Effect 등이 있습니다.
훅에 넘겨주는 함수는 기명 함수로 작성해야 합니다.
익명 함수는 f() {}로 표시되고, 기명 함수는 f 이름() {}로 표시됩니다.
기명 함수를 사용하면 더 정확하게 확인할 수 있습니다.

코드로 기명함수를 표현하면 다음과 같다.
useEffect(() => {}); // xxx
useEffection(function 함수이름() {}); // ooo
프로덕션에서는 react-dom으로만 표시됩니다.
개발 환경에서는 자세한 정보를 볼 수 있습니다.

react-dom > hydrateRoot > App > BoardsPage 순서로 렌더링되었음을 알 수 있습니다.
React가 렌더링하는 과정을 확인하기 위한 도구입니다.
어떤 컴포넌트가 렌더링되었는지, 몇 차례 일어났는지, 어떤 작업이 오래 걸렸는지 확인할 수 있습니다.

렌더링 소요 시간과 각 부분이 업데이트된 이유를 확인할 수 있습니다.

설정 창에서 "Highlight updates when components render"를 활성화하면 렌더링 시 하이라이트 표시가 됩니다.

React 엄격 모드에서는 순수 컴포넌트 확인을 위해 개발 환경에서 렌더링을 두 번 합니다.
"Hide logs during second render in Strict Mode" 옵션을 활성화하면 두 번째 렌더링 로그를 숨깁니다.

"Record why each component rendered while profiling"으로 각 렌더링마다 컴포넌트의 렌더링 이유를 기록합니다.

왼쪽부터 순서대로 아이콘을 설명하겠습니다.
Start Profiling프로파일링이 시작됩니다.
한 번 더 누르면 프로파일링이 종료됩니다.
Reload and Start profiling웹 페이지가 새로고침되면서 동시에 프로파일링이 시작됩니다.
Stop Profiling현재 내용을 모두 삭제합니다.
Load profile프로파일링 결과를 불러옵니다.
Save profile프로파일링 결과를 JSON 파일로 다운로드합니다.
Reload and Start profiling을 이용한 프로파일링 화면입니다.
Flamegraph
렌더 커밋별로 어떤 작업이 일어났는지 보여줍니다.
React 컴포넌트 트리 구조를 확인할 수 있습니다.
너비가 넓을수록 렌더링 시간이 오래 걸렸습니다.
가장 넓은 것은 루트 컴포넌트입니다.
초록색은 빠른 렌더링, 노란색은 느린 렌더링, 회색은 렌더링되지 않은 컴포넌트입니다.

Ranked렌더링 시간이 오래 걸린 순서대로 정렬합니다.


Timeline시간에 따라 컴포넌트에서 일어난 일을 확인합니다. (React 18 이상)

시간 단위로 무엇이 언제 렌더링되었는지, 유휴 시간이 얼마인지 확인할 수 있습니다.
실습을 통해 프로파일링으로 디버깅을 해보겠습니다.
이미지를 하나 업로드하여 미리보기를 보여줄 때 addboard 컴포넌트가 렌더링됩니다.

컴포넌트 탭에서 렌더링 원인을 확인하겠습니다.

14 State의 변경 때문이라고 표시됩니다.
Component 탭에서 14 State를 확인합니다.

코드를 보면 14 State가 preview임을 알 수 있습니다.
export default function Addboard() {
const {
register,
formState: { errors, isDirty, isValid },
handleSubmit,
} = useForm<IFormInput>();
const onSubmit: SubmitHandler<IFormInput> = (d) => {
postArticle({ ...d, image: preview });
};
const { isDesktop } = useScreenDetector();
const [preview, setPreview] = useState("");
// ...
부모 state인 preview가 변경되어 부모 컴포넌트가 리렌더링되고, 이어서 자식 컴포넌트도 리렌더링됩니다.
해결하려면 자식 컴포넌트에서 preview를 변경한 후 부모 컴포넌트로 전달해야 합니다.
하지만 자식에서 부모로 데이터를 전달하는 것은 단방향 데이터 흐름에 반합니다.
로직을 이해하는 선에서 디버깅을 종료했습니다.
React Deep Dive. 김용찬, chapter 6
잘못된 내용이 있다면 댓글로 알려주세요. 감사합니다.