diff --git a/book/300_architecture/313_React_구조_원칙.md b/book/300_architecture/313_React_구조_원칙.md index dfae0a3..cc59d78 100644 --- a/book/300_architecture/313_React_구조_원칙.md +++ b/book/300_architecture/313_React_구조_원칙.md @@ -92,6 +92,7 @@ src/ - 중복 호출 및 무한 루프 방지 - cleanup 함수 적절히 사용 - **Custom Hook 함수 반환**: custom hook에서 반환하는 함수는 `useCallback`으로 메모이제이션 필수 (의존성 배열에 포함 시 무한 루프 방지) +- **Context 값 참조 시 useRef 사용**: `useEffect`에서 Context 값(`book`, `user` 등)을 참조해야 할 때, 의존성 배열에 포함하면 무한 루프 발생 가능. `useRef`로 최신 값을 참조하되 의존성 배열에는 포함하지 않음 ### 성능 최적화 - 불필요한 리렌더링 방지: `React.memo`, `useMemo`, `useCallback` 적절히 활용 @@ -208,7 +209,50 @@ src/ - ETag 사용 시 Ctrl+F5로도 캐시 회피 어려움 - 버전 파라미터가 가장 확실한 방법 -## 13. 참고 +## 13. 레이아웃 최적화 원칙 + +### 사이드바 고정 패턴 +- **문제**: 사이드바가 라우트 컴포넌트 내부에 있으면 라우트 변경 시 리렌더링됨 +- **해결**: 사이드바를 `App.tsx` 레벨로 분리하여 `Routes` 밖에 배치 +- **구조**: + ```tsx + +
+ {/* Routes 밖에 배치 */} + + } /> + +
+
+ ``` +- **장점**: 라우트 변경 시에도 사이드바가 유지되고, 본문만 업데이트됨 + +### Context 값 참조 최적화 +- **문제**: `useEffect` 의존성 배열에 Context 값(`book`, `user` 등)을 포함하면 무한 루프 발생 가능 +- **해결**: `useRef`로 최신 값을 참조하되 의존성 배열에는 포함하지 않음 +- **예시**: + ```tsx + const { book, setBook } = useBook() + const bookRef = useRef(book) + + useEffect(() => { + bookRef.current = book // 최신 값 유지 + }, [book]) + + useEffect(() => { + // bookRef.current로 참조, 의존성 배열에는 포함하지 않음 + if (bookRef.current?.id === blogData.book_id) { + // 같은 book_id면 API 호출 생략 + } + }, [id, setBook]) // book 제외 + ``` + +### BookContext 객체 참조 유지 +- **문제**: 같은 `book_id`인데도 매번 새로운 객체가 생성되어 불필요한 리렌더링 발생 +- **해결**: `BookContext`에서 같은 `book_id`이고 `chapters` 배열이 같으면 객체 참조 유지 +- **구현**: `setBook` 함수에서 `book_id`와 `chapters` 배열을 비교하여 동일하면 업데이트하지 않음 + +## 14. 참고 - 상위 원칙: 이 문서는 일반적인 React 프로젝트 원칙을 다룹니다. - 프로젝트별 특화 규칙: 각 프로젝트의 README나 문서에 추가 규칙 명시