3주차 주제
<모던 리액트 딥 다이브> 스터디를 진행하다가 이런 논란(?)이 있었다.
- 아래와 같은 코드에서, context가 바뀔 때 자식 컴포넌트가 모두 리렌더링 되는 것이 아니라, context가 쓰이는 컴포넌트만 리렌더링 되는 것이었다...!
- 그리고 정말 이상하게도 리렌더링 여부를 확인하기 위한 console.log()는 동작하지 않았지만, React devtools의 하이라이팅은 동작해서 혼란이 가중되었다. (리렌더링 된거다 vs 아니다)
스터디가 끝나고 이러한 현상(context가 쓰이는 컴포넌트만 리렌더링, but 하이라이팅은 모든 자식 컴포넌트)이 일어나는 이유를 이해하기 위해 아래 내용들을 다시 공부해 봐야겠다고 생각했다.
1. useContext
2. children Props
3. React devtools
이번 글에서는 useContext가 정확히 어떤 훅인지 알아보자!
공식문서 - 리액트는 자동으로 context를 쓰는 자식 컴포넌트를 리렌더링한다.
사실 나같은 경우 이전에 처음 Context API를 접하고, Provider인 부모에서 주입시키는 context를 바꾸면, 자식 컴포넌트가 그걸 쓰든 말든 모두 리렌더링된다고 알고 있었다. 이후에 프로젝트에서 상태관리 라이브러리를 이용하게 된 이유 역시 이 리렌더링 때문이었다. 이 생각은 맞았을까?
이 설명 때문에 많이 헷갈렸다. [자동으로 context를 쓰는 자식 컴포넌트를 리렌더링한다] 라는 뜻은, [context를 쓰는 자식 컴포넌트만 리렌더링한다] 라는 뜻이 아니다.
아래 글에서 알아보았던 리렌더링의 조건은 다음과 같았다.
- state 변경
- 부모의 state 변경
즉 리렌더링의 조건을 만족하는 아래 코드와 같은 경우, setCounter 해줄 때마다 당연히 모든 자식 컴포넌트가 리렌더링된다. context를 쓰든 말든 상관없다.
각 컴포넌트의 상태는 다음과 같다.
1번 컴포넌트: 로직 X
2번 컴포넌트: context 가져옴
3번 컴포넌트: context 가져옴
React.memo를 사용해서 각 자식 컴포넌트들을 감싸준다면, 각 자식 컴포넌트가 props으로 받고 있는 것이 없기 때문에 리렌더링이 발생하지 않아야 한다. 그런데 여전히 1번을 제외한 2, 3번 컴포넌트는 리렌더링된다!
이유는 리액트가 [자동으로 context를 쓰는 자식 컴포넌트를 리렌더링하기] 때문이다.
"Provider 인 부모에서 주입시키는 context를 바꾸기 위해 state의 변화가 일어나면, 자식 컴포넌트가 그걸 쓰든 말든 모두 리렌더링된다" 는 맞는 말이었다! 하지만 우리는 context를 사용하지 않는 컴포넌트는 memo를 사용하여 리렌더링을 막을 수 있다.
다음으로
다른 요소들을 배제하기 위해 코드를 변형하였는데, 논란이 되었던 코드는 children이라는 props를 사용하고 있다. 이 props이 어떤 효과를 불러일으키는지 다음 글에서 알아보자.
'TIL > React' 카테고리의 다른 글
[240331] 모던 리액트 딥 다이브 스터디 3주차 - (2) children props (0) | 2024.03.31 |
---|---|
[240320] 리액트의 렌더링, 렌더링 최적화, 메모이제이션 (0) | 2024.03.20 |
[240207] 리액트의 가상 돔(Virtual DOM) (1) | 2024.02.07 |
[240205] 리액트 라이프사이클, useEffect (0) | 2024.02.05 |