Next.js ➡️ app 폴더 ➡️ page.tsx 파일, layout.tsx 파일 (이름이 변하면 안됨)
➡️ 이 안에 있는 컴포넌트 확인
(이 컴포넌트의 이름은 상관 없음, 보통은 Page이고 반드시 export default 된 react 컴포넌트여야 한다.)
page.tsx 예시 코드
export default function page() {
return <h1>Hello NextJs!</h1>
}
import 함수명 from *
사용import { 함수명 } from *
사용layout에는 기본 export 객체가 두 개 있다.
ex)
<img src="/direction.svg"></img>
사용자가 요청한 url에 따라 해당 url에 맞는 페이지를 보여주는 것
SPA 기법을 그대로 유지한 채로 React 페이지 이동처리하는 방법
NextJS 없이 기본적인 React 애플리케이션에서 라우팅하는 방법.
사용자가 입력한 주소를 감지하여 여러 환경에서 동작할 수 있도록 여러 종류의 router component를 제공한다.
url 지정 ➡️ component 요청
예시) /about-us url 접근 ➡️ AboutUs 컴포넌트 연결
하지만, NextJS에서는 이렇게 직접 url을 적어줄 필요가 없다!
NextJS에서는 app 폴더 하단에 폴더만 만들어주면 된다!
app > page folder > page.tsx file
http://localhost:3000/about-us/compony/sales
폴더가 있어도 page 파일이 없으면 실제 경로에 포함되지도, 렌더링되지도 않는다.
따라서 app 폴더 하위에 다른 파일을 넣어도 괜찮다.
위의 예시 같은 경우 page라는 이름의 파일이 존재하지 않으므로 component는 url 이 되지 않는다.
app > not-found.tsx
: 없는 경로로 url 요청시, 보여지는 화면
<a>
태그 사용시, 브라우저의 네비게이션을 사용하게 됨<link>
태그를 사용해야 프레임워크의 네비게이션을 사용하게 됨import Link from "next/link";
export default function Navigation() {
return (
<nav>
<ul>
<li>
<Link href="/">Home</Link>
</li>
<li>
<Link href="/about-us">About Us</Link>
</li>
</ul>
</nav>
);
}
NextJS에는 우리에게 url에 관한 정보를 알려주는 hook
이 有
➡️ router까지 접근할 수 있게 한다.
path name
: user 가 현재 머물고 있는 url
단, usePathname은 오직 client component에서만 작동한다.
리액트 혹은 리액트 클래스형 컴포넌트에서 이용하던 코드를 작성할 필요 없이,
함수형 컴포넌트에서 다양한 기능을 사용할 수 있게 만들어준 라이브러리
ex) useState/useEffect
NextJS가 우리의 react component를 가져와서 브라우저가 이해할 수 있는 html로 변환하는 작업.
React code ➡️ HTML
리액트가 render되는 방식: CSR,
NextJS가 render되는 방식: SSR,
client components
이든, server components
이든, use clients
를 쓴 컴포넌트이든!React가 활성화되는 과정.
➡️ 즉, 단순 HTML을 React application으로 초기화하는 작업.
Hard Navigation
: anchor 태그를 눌러 이동하기 때문에 전체 페이지가 로드되며 페이지를 이동한다.
처음에는 anchors묶음 ➡️ React Component로 변환
(처음에는 dummy html ➡️ 사용자가 페이지에 도착
➡️ 프레임워크가 dummy html을 react application으로 초기화
➡️ hard refresh 없이, navigate 가능)
<button>0</button>
0을 사용자에게 전달 (그냥 0인 걸 받음)단, 이 hydration 과정이 모든 component에 대해 발생하지는 않는다.
➡️ 그렇다면? Client에서 hydrate되는 component는,
오직 use client
지시어를 맨 위에 갖고 있는 component들 뿐이다.
그러니까 나는 interactive할 컴포넌트들에
use client
를 추가하면 되는 것이다.
➡️use client
: backend에서 render되고 frontend에서 hydrate되는 것을 의미한다.
use client를 쓴 컴포넌트들이 client component가 되고,
↔️ 반대로, use client를 안쓴 컴포넌트들이 server component가 된다.
Navigation 같은 거 모든 컴포넌트들에 복사&붙여넣기 하는 건 너무 비효율적.
이를 해결하기 위해서 푸터나 헤더를 쓰는 것인데 이를 만드는데 Layout.tsx.
Layout은 app 폴더 내부의 모든 폴더와 페이지에서 사용된다.
만약 내가 AboutUs 페이지를 간다면, NextJS는 실제로는 layout component로 먼저 가서
Layout 컴포넌트에 있는 export된 default 컴포넌트를 렌더링 한다.
다음 코드의 children
이 AboutUs 컴포넌트를 가르킨다.
해당 컴포넌트는 react 컴포넌트이다.
즉, 컴포넌트를 넣거나 어떤 컴포넌트를 넣을 때, 내부에 있는 컴포넌트들은 자동을 children이라는 props로 바뀌게 된다.
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
네비게이션 컴포넌트는 다음의 코드와 같이 넣어주면 된다.
이를 통해 모든 페이지를 수정하지 않아도 되게 된다.
export default function RootLayout({children,}: Readonly<{ children: React.ReactNode;}>) {
return (
<html lang="en">
<body className={inter.className}>
<Navigation />
{children}
</body>
</html>
);
}
(아니 그럼 네비게이션이 안보이면 좋겠으면 어떻게 하지?
➡️각각의 페이지 별로 다시 레이아웃 페이지를 생성할 수 있다. 이렇게 되면 해당 페이지에 있는 모든 페이지들은 이 레이아웃의 영향을 받게 된다.)
app(page, layout) > about-us(page, layout)
> another-page(page, layout)
...
home에만 국한되는 것은 page.tsx이다.
route groups는 다음과 깉이 폴더 이름을 괄호로 묶어야 한다.
꼭 내보내야 하는 object, 메타데이터라고 부른다.
정적 라우트는 항상 똑같다. /about-us
↔️ 반면, 동적 라우트는 /movies/4545
, /movies/121212
, ... /movies/{id}
동적 라우트를 하고 싶다면 대괄호([]
) 를 사용하면 된다.
이후 url을 다음과 같이 요청하고, props를 log로 찍어보면 결과는 다음과 같이 나오게 된다.
요청: http://localhost:3000/movies/1234?region=kr
log: { params: { id: '1234' }, searchParams: { region: 'kr' } }
Next.JS는 URL을 인식하여 해당 URL의 페이지를 렌더링한다.
➡️ movie detail 페이지로 이동
➡️ props로 id(user가 보낸 id)를 받고 렌더링을 하게 된다.
export default function MovieDetail({params: {id}}: {params:{id:string}}) {
return <h1>Movie {id}</h1>;
}
Server Component 안에 Client Component를 넣을 수는 있지만,
반대로 Client Component 안에 Server Component를 넣을 수는 없다.