Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- oracle
- REST API
- JSON
- HTTP
- SQL
- https
- JavaScript
- Entity
- pls-00103
- Java
- GIT
- Spring Framework
- API
- autowired
- DTO
- spring boot
- vue
- CS
- error
- 깃허브에러
- bean
- 프레임워크
- react
- 뷰
- 개발자기록
- Spring
- Github
- framework
- 어노테이션
- vue3
Archives
- Today
- Total
o-ohi-code 님의 블로그
React 렌더링 과정 본문
React 렌더링
React 프로젝트를 진행하던 중,
예상치 못한 로그인 오류가 계속 발생해서 원인을 추적하게 되었다.
그러다 보니 자연스럽게 react 의 렌더링 과정에 대해 알 게 되었고,
결국 그 렌더링 방식이 로그인 오류의 핵심 원인이었다는 것을 깨닫게 되어 정리를 해보았다.
React의 렌더링 과정에는 크게 2단계로 나뉜다.
Render Phase (렌더 준비 단계)
- 컴포넌트 함수 호출됨
- JSX 평가 → 가상 DOM 트리 구성
- useState, useEffect, useRef 등 Hook들이 등록만 됨 (실행 X)
- 렌더링은 순수해야 함 (랜덤값, API 호출, 상태 업데이트 등 ❌)
Commit Phase (렌더 반영 단계)
- 실제 DOM 업데이트가 여기서 발생
- useLayoutEffect → useEffect 순서로 실행됨
- 이 때 effect는 하위 → 상위 순서로 깊이 우선(DFS) 실행됨
- 리액트는 이 때 Fiber를 통해 변경된 DOM만 최소 반영
ex) 간단한 예시를 들어 설명하자면
import { Routes, Route, Navigate, } from 'react-router-dom';
import React, { useState, useEffect } from 'react'; // ✅ useEffect 추가
import BoardPage from './pages/BoardPage';
import WritePage from './pages/WritePage';
import LoginPage from './pages/loginPage';
import BoardDetailPage from './pages/BoardDetailPage';
function PrivateRoute({ isLoggedIn, children }) {
return isLoggedIn ? children : <Navigate to="/login" />
}
function App() {
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [checkedLogin, setCheckedLogin] = useState(false);
useEffect(() => {
const token = localStorage.getItem("accessToken");
if (token) {
setIsLoggedIn(true);
}
setCheckedLogin(true); // ✅ 복구 완료 표시
}, []);
if (!checkedLogin) return <div>로딩 중...</div>;
return (
<Routes>
<Route path="/" element={<Navigate to="/login" />} />
<Route path="/login" element={<LoginPage setIsLoggedIn={setIsLoggedIn} />} />
<Route
path="/board"
element={
<PrivateRoute isLoggedIn={isLoggedIn}>
<BoardPage />
</PrivateRoute>
}
/>
<Route
path="/write"
element={
<PrivateRoute isLoggedIn={isLoggedIn}>
<WritePage />
</PrivateRoute>
}
/>
<Route
path="/board/:boardId"
element={
<PrivateRoute isLoggedIn={isLoggedIn}>
<BoardDetailPage />
</PrivateRoute>
}
/>
</Routes>
);
}
export default App;
1단계: 브라우저 새로고침(F5)
- 브라우저가 index.html, bundle.js를 다시 불러옴
- React 앱이 새로 시작됨
- App() 컴포넌트가 다시 호출됨
2단계: App 컴포넌트 최초 실행 (Render Phase 시작)
- useState 두 개가 실행됨
- isLoggedIn = false
- checkedLogin = false
- 이제 JSX return 부분이 실행됨
3단계: 조건부 렌더링 평가
if (!checkedLogin) return <div>로딩 중...</div>;
- 현재 checkedLogin === false 이므로
- <Routes> 부분은 아예 실행되지 않음
- BoardPage, WritePage, PrivateRoute, useEffect, saga 등 모두 실행 ❌
👉 이게 바로 "렌더 차단"이 작동한 순간!
4단계: Commit Phase - useEffect 실행
useEffect(() => {
const token = localStorage.getItem("accessToken");
if (token) setIsLoggedIn(true);
setCheckedLogin(true);
}, []);
- 이 코드는 브라우저에 렌더된 후 비동기적으로 실행됨
- localStorage에서 토큰을 꺼내서 로그인 여부 복구
- setIsLoggedIn(true), setCheckedLogin(true) → 상태 업데이트 발생
5단계: 상태 업데이트로 인해 App이 다시 렌더링됨
- 이번엔 checkedLogin === true
- 조건문 통과!
6단계: <Routes> 렌더링됨
<Routes>
<Route path="/board" element={
<PrivateRoute isLoggedIn={isLoggedIn}>
<BoardPage />
</PrivateRoute>
} />
</Routes>
- 이제 진짜로 BoardPage, PrivateRoute, LoginPage 등 필요한 컴포넌트들이 렌더링됨
- 그 안의 useEffect, redux dispatch, saga들도 이제 실행됨!
7단계: PrivateRoute 동작
function PrivateRoute({ isLoggedIn, children }) {
return isLoggedIn ? children : <Navigate to="/login" />;
}
- isLoggedIn === true → children(=BoardPage 등) 렌더 통과
- 로그인 상태에 따라 정상 페이지 or 로그인 페이지 분기
8단계: 최종 페이지 렌더링 완료
- 로그인 상태 복구 완료
- 페이지 컴포넌트 정상 렌더
- 내부 API 호출, saga, 데이터 로딩 등 이제야 실행
정리하면
📦 App() 호출
└ useState 초기화: isLoggedIn=false, checkedLogin=false
└ useEffect 등록
└ return <로딩 중...> (조건부 렌더링 차단)
🔁 Commit Phase
└ useEffect 실행 → 토큰 복구 → 상태 업데이트
🔁 상태 변경 → App() 재렌더
└ checkedLogin = true
└ <Routes> 평가됨
└ <PrivateRoute> 실행
└ isLoggedIn = true → children 통과
└ <BoardPage> 렌더됨
└ 내부 useEffect, saga, dispatch 동작 시작
이 구조의 장점
하위 컴포넌트 초기 실행 방지,
렌더링이 끝난 후 토큰만 복원 가능,
최종적인 로그인 상태 기반 라우팅/페이지 전환 가능
'프로젝트 > React' 카테고리의 다른 글
React 프로젝트 생성 방법 (1) | 2025.04.09 |
---|