요즘 다시 공식문서를 하나씩 읽어가고 있는데, 오늘 읽으면서 이전에 헷갈렸던 걸 다시 공부하는.. 느낌으로 포스팅을 해봅니다.
오늘 공부한 공식문서
Render and Commit – React
The library for web and native user interfaces
react.dev
렌더링 그리고 커밋 – React
The library for web and native user interfaces
ko.react.dev
- Triggering (렌더링 트리거)
- Rendering (렌더링)
- Commit (커밋)

공식문서에서는 트리거 -> 렌더 -> 커밋 의 단계를 음식을 주문하고 주문을 받고 음식을 내오는 예시를 들어 설명하고 있습니다.
● Trigger 트리거
렌더링을 촉발시키는 이유는 2가지 이유가 있습니다.
- 컴포넌트의 첫 렌더링인 경우
- state가 변경되었을 경우
● Rendering 렌더링
- 첫 렌더링에서 React는 루트 컴포넌트를 호출합니다.
- 이후 렌더링에서 React는 state 업데이트에 의해 렌더링이 발동된 함수 컴포넌트를 호출합니다.
공식문서에서 렌더링은 재귀적으로 발동한다고 합니다. 만약 업데이트된 컴포넌트가 또다른 컴포넌트를 반환한다면, 그 컴포넌트를 렌더링하고, 또 그 컴포넌트가 다른 컴포넌트를 반환하면 해당 컴포넌트를 렌더링하게 됩니다.
- 초기 렌더링의 경우 React는 appendChild() DOM API를 사용하여 생성한 모든 DOM 노드를 화면에 표시합니다.
- 리렌더링의 경우 React는 필요한 최소한의 작업(렌더링하는 동안 계산된 것!)을 적용하여 DOM이 최신 렌더링 출력과 일치하도록 합니다.
React는 렌더링 간에 차이가 있는 경우에만 DOM 노드를 변경합니다.
위의 개념을 다시 본 이유는 effect때문이었는데용, 아래공식문서가 좀 생각보다 헷갈려서 위의 개념을 되짚어보았습니다.
Synchronizing with Effects – React
The library for web and native user interfaces
ko.react.dev
- Trigger -> Render -> Commit -> Effect 순으로 실행하게 됩니다.
그리고 헷갈렸던게 커밋단계가 그럼 브라우저에 그리는 paint단계인가 했는데, 그런건 아니고 커밋단계는 리액트가 DOM이 필요한 변경사항을 업데이트하는 단계라고 생각하면 된다.
쉽게 말하면 state가 변경되면 (trigger) -> 렌더링이 발생하게 되는데, 이제막 변경될 컴포넌트들을 와다닥 호출하고 (appendChild) -> 커밋단계에서 변경이 없으면 내비두고, 변경사항이있으면 DOM을 업데이팅 해준다. 그다음 브라우저는 업데이트된 사항을 보고 페인팅을 한다고 생각하면 될 것 같다.
공식문서에서 아래의 사항은 에러가 걸리는데, 그 이유에 대해 알아보자.
import { useState, useRef, useEffect } from 'react';
function VideoPlayer({ src, isPlaying }) {
const ref = useRef(null);
if (isPlaying) {
ref.current.play(); // Calling these while rendering isn't allowed.
} else {
ref.current.pause(); // Also, this crashes.
}
return <video ref={ref} src={src} loop playsInline />;
}
export default function App() {
const [isPlaying, setIsPlaying] = useState(false);
return (
<>
<button onClick={() => setIsPlaying(!isPlaying)}>
{isPlaying ? 'Pause' : 'Play'}
</button>
<VideoPlayer
isPlaying={isPlaying}
src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
/>
</>
);
}
리액트는 내에서 함수형 컴포넌트는 원래 자바스크립트처럼 위에서 아래로 코드를 읽어나간 후, 리턴문이 실행된다.
즉, 실행 순서가
- 컴포넌트의 최상위
- 리턴문
- useEffect hook
순으로 이뤄진다고 보면 되겠다.
아무튼 위의 코드는 런타임 에러가 생기는데, 에러를 보면 ref.current가 null값으로 읽어오지 못하는 것을 볼 수 있다. ref는 컴포넌트 최상단에서 null값으로 정의되고 함수식을 실행할 때 null 값이기 때문에 함수를 실행할 수 없게 된다. (isPlaying이 true이든 false이든지간에)

return문 읽고 나서야 video에 ref가 달리게 되기 때문에 이런 식은 useEffect훅을 통해 해결할 수 있다고 나와있다. 왜냐면 useEffect는 커밋이후에 실행되기때문에 (DOM이 업데이트 되고난 이후에) 실행되기때문에 ref값을 읽을 수 있다는 것 것.~~
참고했던 블로그
[React] useEffect의 실행 시점
Today, What I learned? 작은 기능을 추가하다가 null값이 포함되어서 원래 되던 기능이 안 되는(!) 일이 발생했다. 발견하신 분이 바로 해결해 주셨지만, 마침 그 부분이 useEffect를 사용했던 부분이고..
i-ten.tistory.com
요즘 다시 공식문서를 하나씩 읽어가고 있는데, 오늘 읽으면서 이전에 헷갈렸던 걸 다시 공부하는.. 느낌으로 포스팅을 해봅니다.
오늘 공부한 공식문서
Render and Commit – React
The library for web and native user interfaces
react.dev
렌더링 그리고 커밋 – React
The library for web and native user interfaces
ko.react.dev
- Triggering (렌더링 트리거)
- Rendering (렌더링)
- Commit (커밋)

공식문서에서는 트리거 -> 렌더 -> 커밋 의 단계를 음식을 주문하고 주문을 받고 음식을 내오는 예시를 들어 설명하고 있습니다.
● Trigger 트리거
렌더링을 촉발시키는 이유는 2가지 이유가 있습니다.
- 컴포넌트의 첫 렌더링인 경우
- state가 변경되었을 경우
● Rendering 렌더링
- 첫 렌더링에서 React는 루트 컴포넌트를 호출합니다.
- 이후 렌더링에서 React는 state 업데이트에 의해 렌더링이 발동된 함수 컴포넌트를 호출합니다.
공식문서에서 렌더링은 재귀적으로 발동한다고 합니다. 만약 업데이트된 컴포넌트가 또다른 컴포넌트를 반환한다면, 그 컴포넌트를 렌더링하고, 또 그 컴포넌트가 다른 컴포넌트를 반환하면 해당 컴포넌트를 렌더링하게 됩니다.
- 초기 렌더링의 경우 React는 appendChild() DOM API를 사용하여 생성한 모든 DOM 노드를 화면에 표시합니다.
- 리렌더링의 경우 React는 필요한 최소한의 작업(렌더링하는 동안 계산된 것!)을 적용하여 DOM이 최신 렌더링 출력과 일치하도록 합니다.
React는 렌더링 간에 차이가 있는 경우에만 DOM 노드를 변경합니다.
위의 개념을 다시 본 이유는 effect때문이었는데용, 아래공식문서가 좀 생각보다 헷갈려서 위의 개념을 되짚어보았습니다.
Synchronizing with Effects – React
The library for web and native user interfaces
ko.react.dev
- Trigger -> Render -> Commit -> Effect 순으로 실행하게 됩니다.
그리고 헷갈렸던게 커밋단계가 그럼 브라우저에 그리는 paint단계인가 했는데, 그런건 아니고 커밋단계는 리액트가 DOM이 필요한 변경사항을 업데이트하는 단계라고 생각하면 된다.
쉽게 말하면 state가 변경되면 (trigger) -> 렌더링이 발생하게 되는데, 이제막 변경될 컴포넌트들을 와다닥 호출하고 (appendChild) -> 커밋단계에서 변경이 없으면 내비두고, 변경사항이있으면 DOM을 업데이팅 해준다. 그다음 브라우저는 업데이트된 사항을 보고 페인팅을 한다고 생각하면 될 것 같다.
공식문서에서 아래의 사항은 에러가 걸리는데, 그 이유에 대해 알아보자.
import { useState, useRef, useEffect } from 'react';
function VideoPlayer({ src, isPlaying }) {
const ref = useRef(null);
if (isPlaying) {
ref.current.play(); // Calling these while rendering isn't allowed.
} else {
ref.current.pause(); // Also, this crashes.
}
return <video ref={ref} src={src} loop playsInline />;
}
export default function App() {
const [isPlaying, setIsPlaying] = useState(false);
return (
<>
<button onClick={() => setIsPlaying(!isPlaying)}>
{isPlaying ? 'Pause' : 'Play'}
</button>
<VideoPlayer
isPlaying={isPlaying}
src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
/>
</>
);
}
리액트는 내에서 함수형 컴포넌트는 원래 자바스크립트처럼 위에서 아래로 코드를 읽어나간 후, 리턴문이 실행된다.
즉, 실행 순서가
- 컴포넌트의 최상위
- 리턴문
- useEffect hook
순으로 이뤄진다고 보면 되겠다.
아무튼 위의 코드는 런타임 에러가 생기는데, 에러를 보면 ref.current가 null값으로 읽어오지 못하는 것을 볼 수 있다. ref는 컴포넌트 최상단에서 null값으로 정의되고 함수식을 실행할 때 null 값이기 때문에 함수를 실행할 수 없게 된다. (isPlaying이 true이든 false이든지간에)

return문 읽고 나서야 video에 ref가 달리게 되기 때문에 이런 식은 useEffect훅을 통해 해결할 수 있다고 나와있다. 왜냐면 useEffect는 커밋이후에 실행되기때문에 (DOM이 업데이트 되고난 이후에) 실행되기때문에 ref값을 읽을 수 있다는 것 것.~~
참고했던 블로그
[React] useEffect의 실행 시점
Today, What I learned? 작은 기능을 추가하다가 null값이 포함되어서 원래 되던 기능이 안 되는(!) 일이 발생했다. 발견하신 분이 바로 해결해 주셨지만, 마침 그 부분이 useEffect를 사용했던 부분이고..
i-ten.tistory.com