💡 서버에서 렌더링된 페이지와 클라이언트 사이드에서 렌더링된 페이지 간에 HTML 속성 불일치로 발생하는 에러문제Next.js에서 다크 모드와 같은 테마 기능을 손쉽게 구현할 수 있도록 도와주는 라이브러리로 next-themes를 많이 이용하길래 나도 한 번 사용해봤다.테마 기능은 잘 동작한다. 다만, 콘솔창에서 위와 같은 에러가 발생하는데 서버에서 렌더링된 페이지와 클라이언트 사이드에서 렌더링된 페이지 간에 HTML 속성 불일치로 발생하는 에러임을 확인 위처럼 서버에서 렌더링된 페이지의 HTML 속성과 클라이언트에서 렌더링된 페이지간의 속성 차이가 발생하는 것을 볼 수 있다.해결클라이언트 사이드에서 컴포넌트가 마운트 됐을 때, ThemeProvider를 렌더링하게끔 useEffe..
Programming
useSelectedLayoutSegement 활성화된 링크(Active link)를 감지하기 위해선 브라우저단에서 가능하다. 사용자가 어떠한 페이지에 있는지 알아야하기 때문이다. 브라우저 환경은 클라이언트 사이드이므로 서버 컴포넌트가 아닌 클라이언트 컴포넌트로 작업해야 한다. useSelectedLayoutSegment hook은 레이아웃보다 한 단계 아래의 활성화된 route segment를 획득할 수 있다. "use client"; import { useSelectedLayoutSegment } from "next/navigation"; export default function NavMenu() { const segment = useSelectedLayoutSegment(); return } 위..
Parallel Routes 동일한 레이아웃(동일한 화면) 내에서 하나 이상의 페이지를 동시에 또는 조건부로 렌더링할 수 있다. 병렬 라우트를 정의할 때 @folder 형태의 슬롯이 필요하다. 슬롯은 route segment에서 제외되기 때문에 URL 구조에 영향을 주지 않는다. 슬롯은 부모 layout에 props로 전달된다. 사용 예시 "src/app/page.tsx"의 메인 페이지와 동시에 특정 경로 페이지를 동시 렌더링하고 싶다면 병렬 라우트를 이용한다. 다만, 공통 레이아웃에서 페이지를 동시에 렌더링하기 위해선 page.tsx가 디렉토리의 동일 계층에 위치해야 한다. "src/app/(beforeLoin)" 아래에 슬롯(@modal)과 layout.tsx를 동일 계층에 위치시킨 다음 별도의 im..
template.tsx 템플릿은 각 하위 레이아웃 또는 페이지를 래핑한다는 점에서 레이아웃과 유사하다. 사용자가 템플릿을 공유하는 경로 사이를 탐색할 때 컴포넌트의 새 인스턴스가 마운트되고, DOM 요소가 다시 생성되며, 상태가 유지되지 않고, 효과가 다시 동기화된다. useEffect(ex: 페이지 보기 로깅) 및 useState(ex: 페이지별 피드백 양식) 에 의존하는 기능은 template가 적합하다. 💡 layout과 template는 공존해서는 안된다. 둘 중 하나를 택하도록 하자. layout.tsx의 경우 라우팅간에 리렌더되지 않지만, template.tsx는 컴포넌트가 새로 마운트되므로 특정 동작이 필요할 경우 채용한다. 는 HTML 요소를 확장한 route 간 prefetching 및 ..
app router 라우팅 처리될 페이지들이 포함될 디렉토리 파일 시스템 기반으로 라우팅 처리 자동 코드 스플리팅 수행(번들 사이즈 down 효과) 💡 path alias 경로 별칭 설정 가능 (next.js는 기본적으로 @으로 설정됨) 상대 경로 ex) ../../app/layout 절대 경로 ex) @/app/layout 브라우저 주소 app 폴더에 반영하기 layout.tsx 여러 페이지간에 공유되는 UI (Navbar, header, footer 등 공통적으로 표현될 UI) 레이아웃은 중첩될 수 있다. (루트 레이아웃 -> 특정 레이아웃 -> 특정 페이지) children prop으로 페이지 또는 중첩 레이아웃을 전달받는다. export default function DashboardLayout(..
💡 상태? 웹 애플리케이션의 시간이 지남에 따라 혹은 상호작용에 의해 변화할 수 있는 데이터 상태관리? - 유저와의 상호작용을 위해, 상태를 조작하고 다루는 모든 작업 상태관리가 중요한 이유? - 상태관리는 컴포넌트의 불필요한 리렌더링을 방지하고 의도하지 않은 UI/UX를 방지하며 앱의 유지보수성을 높입니다. 과거 jQuery를 사용하던 시절 데이터 속성(dataset)을 이용해서 상태관리를 수행했는데, DOM 중심의 상태 관리로직을 구성하게 되므로, 상태 변화의 추적이 어렵다는 단점이 존재합니다. dataset 추후, SPA 프레임워크 앵귤러, 뷰, 리액트의 등장으로 DOM 접근 없이 데이터가 변경되면 출력도 자동으로 변경되도록 처리가 가능해졌으며, 데이터 중심의 상태관리 로직의 구성이 가능해지고 이는..
var ES5까지 변수를 선언할 수 있는 유일한 방법은 var키워드를 사용하는 것이었다. var 사용 시 몇가지 주의할 점이 존재한다. - 변수 중복 선언 허용 var 키워드로 선언한 변수는 중복 선언이 가능하다. var x = 1; var y = 1; var x = 100; var y; console.log(x) // 100 console.log(y) // 1 - 함수 레벨 스코프 var 키워드로 선언한 변수는 오로지 함수 레벨 스코프를 따른다. 함수 외부에서 선안한 변수는 코드 블록 내에 선언하여도 모두 전역 변수가 된다. 따라서 의도치 않게 변수의 중복 선언이 발생할 수 있다. var x = 1; if (true) { var x = 10; // 함수 코드 블럭이 아니므로 변수의 중복 선언이 발생함 ..
1. 문제 상황 등록 상품 수정 시 이미지를 제외한 입력 필드만 변경했을 경우 invalidateQueries가 호출되지 않는다. 파일: use-fetch-console.ts 2. 원인 storageService.deleteFiles 메소드 내부에서 fileURLs 인자가 배열이 아니거나 undefined일 경우 throw Error를 던지므로 다음 코드가 실행되지 않고 catch block으로 코드 흐름이 넘어갔음 3. 해결 방법 에러를 던지지 않도록 변경, throw Error 코드 제거 AS-IS TO-BE 4. 배경지식 Error 생성자 함수로 에러 객체를 에러가 발생하는 것은 아니다. 에러 객체 생성과 에러 발생은 엄연히 의미가 다르다. 에러를 발생시킬려면 throw 키워드로 에러 객체를 던져..