[React] 그래서 렌더링이 뭔데?
이 글을 쓰는 계기,,
지금껏 리액트를 공부해오면서
입에서 “렌더링”이라는 단어를 셀 수도 없이 많이 뱉었다.
하지만, useEffect와 useLayoutEffect에 대해서 알아보면서
도대체 render와 paint의 차이는 뭐야? 어? render의 정확한 의미가 뭐지?
그냥 눈에 보이게끔 하는 게 render 아니야? 하면서 문득
아 공부를 잘못하고 있었구나 하는게 느껴졌다.
그래서 React 공식 문서를 토대로 정리를 해보았다.
그래서 렌더링이 뭔데 ?
“Rendering” is React calling your components.
- React 공식 문서
리액트 공식문서에서 설명하기를, 렌더링은 컴포넌트의 호출이라고 한다.
컴포넌트가 화면에 나타나기 전, 모든 컴포넌트들은 반드시 React에 의해 render되어야 한다.
만약 우리가 식당이라고 가정을 해보자.
- 웨이터는 우리의 주문을 받아 주방에 전달하고
(Trigger a Render) - 주방에서는 음식을 만들어 내어주고
(Rendering the Component) - 웨이터는 그 음식을 받아 우리에게 서빙을 한다.
(Commiting to the DOM)
이 3가지의 Step이 React 공식문서에서 설명하는 Render & Commit이라고 한다.
더 자세히 들어가보자.
Render & Commit 3Steps
1. Trigger a Render
컴포넌트의 렌더링이 발생하는 데에는 2가지 이유가 있다 :
- 컴포넌트의 최초 렌더링
- 컴포넌트(혹은 부모 컴포넌트)의 상태 업데이트
1-1. Initial Render (컴포넌트 최초 렌더링)
React app을 실행할 때, 우리는 최초의 렌더링을 일으켜야 한다.
createRoot를 호출한 다음, component와 함께 render메서드를 호출하여 수행한다.
// index.js
import { createRoot } from "react";
import App from "./App.js";
const root = createRoot(document.getElementbyId("root"));
root.render(<App />);
1-2 Re-renders when state updates
(상태 변경에 의한 리렌더링)
컴포넌트 최초의 렌더링이 일어나고 난 후, set
function을 사용한
상태(state) 업데이트를 통해, 추가적인 렌더링 일으킬 수 있다.
컴포넌트 상태의 업데이트는 자동으로 해당 컴포넌트를 렌더링 대기열에 추가하게 된다.
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<>
<button onClick={setCount(count - 1)}>-</button>
<span>{count}</span>
<button onClick={setCount(count + 1)}>+</button>
</>
);
}
2. React renders your components
render를 발생시키고 난 후, React는 컴포넌트에게 화면에 띄워야 할 것이 무엇인지 찾아오도록 요청한다.
“Rendering” is React calling your components.
직역하자면, 렌더링은 컴포넌트를 호출하는 React를 의미한다.
- 최초 렌더링 시, React는 root 컴포넌트를 호출한다.
- 리렌더링 시, React는 상태 업데이트를 통해 render를 발생시킨
컴포넌트를 호출한다.
이 과정은 재귀적이다.
만약 렌더링된 컴포넌트가 다른 컴포넌트를 반환할 때, React는 컴포넌트를 다음 컴포넌트를 render한다.
이 과정이 더 이상 중첩된 컴포넌트가 없을 때까지 반복된다. 그 후 React는 화면에 띄워야 할 것이 무엇인지 정확히 인지한다.
3. Commiting to the DOM
컴포넌트 렌더링 후, React는 DOM을 수정한다.
- 최초 렌더링 시, React는
appendChild()
DOM API를 사용하여 모든 DOM 노드들을 화면에 출력한다. - 리렌더링 시, React는 DOM이 최신 렌더링의 출력과 일치하도록 렌더링 시 계산된 최소한의 필수 작업을 진행한다.
리액트는 변경 사항이 있는 DOM노드들만 바꾼다.
export default function Clock({ time }) {
return (
<>
<h1>{time}</h1>
<input />
</>
);
}
위 코드에서 time의 변경에 따라 h1의 컨텐츠는 업데이트 되지만,
React는 input태그는 건드리지 않기 때문에, input 태그에는 리렌더링이 발생하지 않는다고 한다.
Epilogue: Browser Paint
렌더링과 DOM요소 업데이트가 끝나고 난 후, 브라우저는 화면을 repaint 한다. 우리에겐 repaint를 포함하여 화면이 출력되는 모든 과정을 “browser rendering”이라고 잘 알려져 있지만, React에서는 혼돈을 막기 위해 “painting” 이라고 명명하였다.
Conclusion
- Render = 컴포넌트 호출
- Commit = DOM에 DOM node들을 적용
- Painting = 브라우저에 의한 화면 출력
➡️ Render와 Commit, Painting은 전부 다 다른 개념이다.
댓글남기기