리액트 공식문서를 살펴보면,
This process is recursive: if the updated component returns some other component, React will render that component next, and if that component also returns something, it will render that component next, and so on. The process will continue until there are no more nested components and React knows exactly what should be displayed on screen.
이런 구문이 있다. return값에 컴포넌트가 있다면, 해당 컴포넌트를 리렌더링 하고, 또 해당 컴포넌트의 return값에 컴포넌트가 있다면, 리렌더링 하고,... 재귀적으로 계속해서 반복 한다고 한다.
이게 무슨 의미일까?
부모 컴포넌트에서 자식 컴포넌트를 return 할때,
부모 컴포넌트의 실행 컨텍스트에 아래와 같은 변수들을 저장하게 된다.
부모 컴포넌트가 리렌더링 되면, 컴포넌트 안에 할당 했던 모든 변수들은 재할당이 되기 때문에(실행 컨텍스트의 내용이 변경되기 때문에), children 컴포넌트 역시 재할당이 되며 리렌더링이 되는 것이다.
그래서 리렌더링을 막기 위해 useCallback으로 함수(여기선 FunctionComponent)의 메모리 주소를 memoization 하는 것이다.
ref: https://overreacted.io/react-as-a-ui-runtime/#recursion
추가로 가상돔 구조는 아래와 같이 생겼다.
{
type: 'div',
props: {
className: 'my-class',
onClick: handleClick
},
children: [
{
type: 'p',
props: {},
children: ['Hello World']
},
{
type: 'button',
props: {
disabled: false
},
children: ['Click Me']
}
]
}