일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 클래스
- lazy()
- react
- 초기마운트
- Database
- 리액트훅
- NextJs
- useLayoutEffect
- react-hook-form
- useEffect
- 리액트 훅
- docker
- key
- CSR
- SSR
- msw
- 리액트
- reactquery
- Firebase
- next-cookies
- react-hook
- express
- 모던자바스크립트
- ErrorBoundary
- Today
- Total
한우의 개발일기
리액트의 리렌더링 본문
리액트에서의 렌더링
컴포넌트 함수가 호출되서 VDOM에 반영되는것.
(더 간단하게는 컴포넌트 함수가 호출되는것 -> 어차피 return을 통해 VDOM에 반영되니까)
리렌더링이란?
Render Phase vs Commit phase
간단하게 얘기를 하자면 리액트에서 VDOM에 컴포넌트가 렌더링이 되고 state 같은것들이 바뀌면 새롭게 VDOM 생기면서 렌더링을 해줍니다
그때 Render Phase에서 DOM 트리를 순회하면서 변경된 부분을 비교합니다.
달라졌다면 그때 체크(더티체크)를 하고 달라진걸 비교해서 재조정을 합니다.
이때 실제 브라우저에 적용을합니다. 이때 전체 트리를 적용하는게 아닌 달라진 부분만을 RealDOM 에 적용을 합니다.
이 달라진걸 적용을하는것을 CommitPhase 라고 합니다.
이때 달라졌다라는걸 체크하는걸 리액트는 어떻게 할까요??
달라졌다라는건 보통 4가지가 있는데요
- 조건부 렌더링을 통하여 요소가 사라졌을시
예를들어 isOpen 과 같은 조건부로 요소가 사라지고 생기는 경우 - type 이 달라졌을시(여기서의 타입은 타입스크립트의 타입이 아닌 쉽게 말해 html 태그와 커스텀 컴포넌트들입니다)
위에 두 부분이 달라졌을시에는 리액트에서 아예 언마운트를 시켰다가 다시 마운트를 시킵니다
- props 가 달라졌을시
props 가 달라졌을시에는 언마운트 시킨후에 다시 마운트 하는것은 DOM 트리에 부담이되고 비효율적이라 attribute 만 변경을 시킵니다.
그렇다면 만약에 props 만 바뀌고 타입이 변하지 않는다면??
예시문제)
체크 박스를 클릭했을때 렌더링 되는 결과는 몇번 일까요? (1번 or 2번)![]()
import { useEffect, useState } from 'react'
import './App.css'
export default function App() {
const [isCompany1, setIsCompany1] = useState(false);
const [isCompany2, setIsCompany2] = useState(false);
return (
<div className="App">
<h1>개인이신가요 사업자이신가요?</h1>
<p>체크박스를 켜고 끄면서 개인과 사업자 입력 필드를 전환해보세요.</p>
<div className="container">
<div className="column">
<h4>Input이 언마운트되고 마운트됩니다.</h4>
<label>
<input type="checkbox" onChange={() => setIsCompany1(!isCompany1)} />
사업자인 경우 체크하세요.
</label>
{isCompany1 ? (
<Input label="사업자등록번호" placeholder="12자리 숫자 입력" onChange={() => {}} id="company-tax-id" />
) : (
<TextPlaceholder />
)}
</div>
<div className="column">
<h4>Input이 리렌더링됩니다.</h4>
<label>
<input type="checkbox" onChange={() => setIsCompany2(!isCompany2)} />
사업자인 경우 체크하세요.
</label>
{isCompany2 ? (
<Input label="사업자등록번호" placeholder="12자리 숫자 입력" onChange={() => {}} id="company-tax-id" />
) : (
<Input label="주민등록번호" placeholder="숫자 8자리와 문자 3자리 입력" onChange={() => {}} id="person-tax-id" />
)}
</div>
</div>
</div>
);
}
const Input = ({ onChange, label, placeholder, id }) => {
useEffect(() => {
console.info(Input이 마운트되었습니다.);
}, []);
return (
<>
<label htmlFor={id}>{label}</label>
<input type="text" onChange={onChange} id={id} placeholder={placeholder} />
</>
);
};
const TextPlaceholder = () => <p>안녕하세요! 세금 내실 필요 없습니다.</p>;
결과는 1번 입니다
이 이유는 조건부 랜더링이긴 하지만 Input 컴포넌트는 타입이 변경되지않고 props 만 달라졌기 때문에 VDOM 입장에서는 타입이 같기 때문에 remove 한뒤 append 를 하는것이아닌 (onChange, label, placeholder, id ) 만 변경이 되기 때문에
value는 남아있게 됩니다
- Key가 달라졌을시
키가 달라진다면 VDOM 에서는 아예 다른것이라 판단을 하고 remove 한 뒤에 다시 append 를 하게 됩니다.
키에는 '고유값'을 넣어야 하는 이유도 여기에 있습니다
이때 키의 활용법은 폼을 초기화 할때, 페이지네이션을 활용할때 사용을 할 수 도 있습니다.
페이지네이션에서 활용법은 예를 들면 한 페이지에서 보여줘야 되는정보가 props에 따른 이미지, title 과같은 것들만 변경이 되고 그것들을 감싸는 껍대기(레이아웃) 은 같다면 같은 키를 주고 안에 Props 만 변경되게하여 껍데기는 살아있게 하여 사용자가 페이지를 이동했을때 깜빡거리는 경험을 하지 않게 할 수 있습니다
'React' 카테고리의 다른 글
리액트의 초기 마운트 (0) | 2025.02.13 |
---|---|
리액트의 내부개요 (0) | 2025.02.13 |
React-hook-form에서 watch 와 useWatch (0) | 2024.11.11 |
SSR과 CSR (2) | 2024.11.11 |
커스텀훅 vs 고차 컴포넌트 (0) | 2024.11.11 |