
리액트 애플리케이션 트리 안에 있는 모든 컴포넌트들이 현재 자신들이 가지고 있는 props와 state의 값을 기반으로 어떻게 UI를 구성하고 이를 바탕으로 어떤 DOM 결과를 브라우저에 제공할 것인지 계산하는 일련의 과정
<Child key={Math.random()} >과 같이 랜덤한 값을 key에 할당하면 memo로 선언해도 매번 리렌더링이 일어나기에 key를 활용해 강제로 리렌더링을 일으키는 것이 가능하다.렌더링 프로세스가 시작되면 리액트는 컴포넌트의 루트에서부터 차근차근 아래쪽으로 내려가면서 업데이트가 필요하다고 지정돼 있는 모든 컴포넌트를 찾는다.
여기서 업데이트가 필요하다고 지정된 컴포넌트를 발견하면 클래스 컴포넌트의 경우 클래스 내부의 render() 함수를 실행하게 되고,
함수 컴포넌트의 경우 FunctionComponent() 자체를 호출한 뒤에, 그 결과물을 저장한다.
렌더링 결과물은 JSX 문법으로 구성되어 있고, 자바스크립트로 컴파일 되면서 React.createElement()를 호출하는 구문으로 변환된다.
function Hello() {
// JSX 문법
return (
<TestComponent a={35} b="yceffort">
안녕하세요
</TestComponent>
)
}
function Hello() {
// React.createElement()를 호출하는 구문으로 변환
return React.createElement(
TestComponent,
{ a: 35, b: "yceffort"},
'안녕하세요',
)
}
렌더링 프로세스가 실행되면서 각 컴포넌트의 렌더링 결과물을 수집한 다음, 가상 DOM과 비교해 실제 DOM에 반영하기 위한 모든 변경 사항을 차례차례 수집한다.
모든 변경 사항을 하나의 동기 시퀀스로 DOM에 적용해 변경된 결과물이 보이게 된다.
리액트의 렌더링은 렌더 단계와 커밋 단계 총 두 단계로 분리되어 실행된다.
컴포넌트를 렌더링하고 변경 사항을 계산하는 모든 작업
렌더 단계의 변경 사항을 실제 DOM에 적용해 사용자에게 보여주는 과정
리액트의 렌더링이 일어난다고 해서 무조건 DOM 업데이트가 일어나는 것은 아니다.

import { useState } from 'react'
export default function A() {
return (
<div className="App">
<h1>Hello React</h1>
<B />
</div>
)
}
function B() {
const [counter, setCounter] = useState(0)
function handleButtonClick() {
setCounter((previous) => previous + 1)
}
return (
<>
<label>
<C number={counter} />
</label>
<button onClick={handleButtonClick}>+</button>
</>
)
}
function C({ number }) {
return (
<div>
{number} <D />
</div>
)
}
function D() {
return <>리액트 재밌다!</>
}
컴포넌트를 렌더링하는 작업은 하위 모든 컴포넌트에 영향을 미친다.
부모가 변경됐다면 props가 변경됐는지와 상관없이 무조건 자식 컴포넌트도 리렌더링 된다.