https://github.com/Ark-inflearn/inflearn-clone-front/issues/83
sprint 라고 할 수 있을지 모르겠지만
Ark 프로젝트 진행을 하다보니 기술부채를 쌓고 넘어갔던 문제들을 이번에 두 가지만 해결하고자 한다.
위 두 가지는 독립적인 주제가 아닐 수 있다.
그렇지만 리렌더링 조건 부터 알아보겠다.
우선 알아보기 전에 내가 알고 있는 것을 미리 적어보려 한다.
내가 알기론 state(redux store 또는 useState)와 prop이 바뀌면 렌더링이 다시 되는 것으로 대략적으로 알고 있다.
그런데 내가 착각했던 것은 state나 prop에 영향을 직접적으로 받는(그 값을 사용하는) 컴포넌트만 바뀌는 줄 알았는데
이번에 이 글 맨 윗 부분링크인 이슈83에선 state를 직접 사용하지 않는 컴포넌트도 다시 렌더링이 되는 현상을 발견했다.
이번 기회에 확실히 컴포넌트가 렌더링이 다시 되는 조건을 명확히 알고 넘어가면 좋겠다는 생각이 들었다.
1. state 변경이 있을 때
2. 새로운 props이 들어올 때
3. 부모 컴포넌트가 렌더링 될 때
4. shouldComponentUpdate에서 true가 반환될 때
// app.js
import TestPage from './components/TestPage';
const DivDiv = styled.div``;
function App() {
const [test, setTest] = useState(0);
function onClickButton() {
setTest(prev => (prev += 1));
}
return (
<div>
<nav>
<button onClick={onClickButton}>test button</button>
{test}
</nav>
<header>
<div>header</div>
<div>header</div>
<div>header</div>
{/* <DivDiv>header</DivDiv> */}
</header>
<main>
<TestPage />
</main>
<footer>
<div>footer</div>
<div>footer</div>
<div>footer</div>
</footer>
</div>
);
}
// TestPage.js
const TestPage = () => {
return (
<div>test</div>
);
};
export default TestPage;
state가 변화하면 styled-component를 사용한 모든 컴포넌트들이 re-rendering되기 때문에 이것이 성능에 얼마나 영향을 미치는지는 따로 확인할 방법을 생각해봐야할 것이다.
자칫 issue #83 만 생각해서 state가 변하면 모든 엘리먼트가 re-rendering되는 줄 알았는데 그것은 아니었다.
import된 컴포넌트들이 re-rendering 되는 이유는 조건3. 부모컴포넌트가 렌더링될 때 자식 컴포넌트도 렌더링 되기 때문이다.
styled-components가 re-rendering 되는 이유는 두 가지 중 하나로 추정 된다.
사실 re-rendering을 고려해서 컴포넌트를 세세하게 작성하기엔 너무 불편할 것이다.
중요한 것은 이것이 성능에 얼마나 악영향을 미치는지 혹은 생각보다 너무 미미해서 티가 아에 안날정도일 수도 있다.
개인적으론 굳이 눈에 띄게 성능에 문제가 있는 경우가 아니라면 굳이 re-rendering을 꼼꼼하게 고려하지 않아도 될 것 같다.
const App = () => {
const [message, setMessage] = React.useState('');
return (
<>
<Tile message={message} />
<Tile />
</>
);
};
The red dots again represent renders.
In React, this means calling the render function. In the real DOM, this means re-painting the UI.
빨간색으로 표시된 것은 컴포넌트 함수의 실행을 의미하지만 실제로 render 되는 것은 다를 수 있다.
그러나 render 함수의 실행은 두 가지 단점을 가진다.
구성 요소가 업데이트되어야 하는 시점 제어
React.memo
페이지 전체 레이아웃에서 페이지가 바뀔 때마다 children 페이지가 적용되는 방식으로 작성된 곳에 memo를 적용해봐도 소용이 없었다.
const CourseLayout = React.memo(({ children }: IProps) => {
// render page
});
// memo를 적용해도 달라지는 것은 없었다.