* NextJS 프로젝트 설치 및 실행 *
https://cocococo.tistory.com/42
* Source Code *
https://github.com/kangilbin/React.js/tree/master/nextjs-study
1. Routes
pages 폴더 안에 새로운 page 파일을 넣게 되면 자동으로 이동할 수 있다.
( about.tsx )
export default function Potato() {
return "about";
}
- export default로 만들어 주어야한다.
- 함수명은 상관없다.
- 파일 이름이 그대로 url로 들어간다.
- index 파일은 메인 홈페이와 연결되어있다. http://localhost:3000 => index 페이지
2. Routing
import Link from "next/link";
export default function NavBar() {
return (
<nav>
<Link href="/"><a className="hello" style={{color:black}}>Home</a></Link>
<Link href="/about"><a>About</a></Link>
</nav>
);
};
- 따로 Router 라이브러리를 설치하지 않아도 작동한다.
- Routing 하는데 <a /> 태그를 사용할 수 없고, Link태그를 사용해야 한다.
// <a />태그만 단독 사용 x
<a href='URL'>About</a>
// Link 내부에 <a />
<Link href="/about"><a>About</a></Link>
- 새로고침 할 경우 페이지 전체를 렌더링 하지 않기 위해 NextJS에서 라우팅 시에 사용해야 하는 방법이(Link 컴포넌트) 존재한다.
2-1) Props 전달
import Link from "next/link";
export default function NavBar() {
return (
<nav>
<Link href="/"><a className="hello" style={{color:black}}>Home</a></Link>
</nav>
);
};
- Prop을 주기 위해서 <Link /> 안에 <a />를 사용하여 <a /> 태그에 Prop 값을 전달해 준다.
2-2) useRouter Hook ( URL 정보)
useRouter Hook은 location에 관한 정보를 가지고 있다. asPath, back, basePath 등
import Link from "next/link";
import { useRouter } from "next/router";
export default function NavBar() {
const router = useRouter();
return (
<nav>
<Link href="/">
<a style={{color: router.pathname === "/" ? "red" : "blue"}}>Home</a>
</Link>
<Link href="/about">
<a style={{color: router.pathname === "/abount" ? "red" : "blue"}}>About</a>
</Link>
</nav>
);
};
- pathname에 페이지 url를 가지고 있다.
3. Dynamic Routes (동적 라우트)
- 패키지 경로를 url 경로와 맵핑해 준다.
* http://{URL} / {패키지 경로} *
http://localhost:3000/movies/all
3-1) 서브 경로의 index 페이지 설정
- /moves 주소와 하위 주소까지 가지고 싶다면 moves 폴더 안에 index 이름으로 파일을 만든다.
( http://localhost:3000/movies => index 페이지)
3-2) 변수를 포함하는 Dynamic URL
- 파일명을 대괄호([]) 만들면 Dynamic URL이라고 알려준다.
- 파일명([id])과 전달받은 파라미터 변수명이 같아야 한다.
* http://{url}/movies/:id *
ex) http://localhost:3000/movies/539681
(URL 객체로 페이지 이동)
import { useRouter } from 'next/router'
export default function ReadMore({ post }) {
const router = useRouter()
return (
<button
type="button"
onClick={() => {
router.push({
pathname: '/movies/[id]',
query: { id: post.id },
})
}}
>
Click here to read more
</button>
)
}
( [id].tsx )
import { useRouter } from "next/router";
export default function Detail(){
const route = useRouter();
console.log(route)
return "detail";
}
- 함수명은 상관없다.
- 파라미터는 route Object의 query안에 있다. key값은 대괄호 안에 있는 파일명이랑 동일하다.
3-3) Navigating 방법 예
import Seo from "./../components/Seo";
import Link from "next/link";
import { useRouter } from "next/router";
interface IMoviProp {
id: number;
original_title: string;
poster_path: string;
}
export default function Home({ results }: { results: IMoviProp[] }) {
const router = useRouter();
const onClick = (id: number) => {
router.push(`/movies/${id}`);
};
return (
<div>
<Seo title="Home" />
{results?.map((movie) => (
<div onClick={() => onClick(movie.id)} className="movie" key={movie.id}>
<img src={`https://image.tmdb.org/t/p/w500${movie.poster_path}`} />
<h4>
<Link href={`/movies/${movie.id}`}>
<a>{movie.original_title} </a>
</Link>
</h4>
</div>
))}
</div>
);
}
( 마스킹 처리(as) url로 state 넘겨주는 방법 )
<Link
href={{
pathname: `/movies/${movie.id}`,
query: {
id,
title: "potatos",
},
}}
as={`/movies/${movie.id}`}
>
<a>{movie.original_title} </a>
</Link>
( 이벤트를 사용한 url로 state 넘겨주는 방법 )
const router = useRouter();
const onClick = (id: number) => {
router.push({
pathname: `/movies/${id}`,
query: {
id,
title: "potatos",
},
});
};
(이벤트를 사용한 url 마스킹 처리 방법 )
const onClick = (id: number) => {
router.push(
{
pathname: `/movies/${id}`,
query: {
title: "potatos",
},
},
// 마스킹하고 싶은 url 입력
`/movies/${id}`
);
};
3-4) catch-all URL
뭐든 무한대로 잡아내는 url이다.
- […id] : 파일명(파일명은 상관없음) 앞에 … 을 주게 되면 모든 주소에 접근할 수 있다.
- query값이 배열로 변경된다.
( [...params].tsx param 가져오기 )
import { NextRouter, useRouter } from "next/router";
// Obejct가 아니기 때문에 type으로 선언문으로 배열값의 type을 지정해준다.
type routerParam = [string, string];
export default function Detail() {
const router: NextRouter = useRouter();
// 최초 렌더링시 HTML 파일만 내려오기 때문에 useRouter 값을 제대로 불러오지 못한다 그렇기 때문에 초기에 빈배열 추가해준다.
const [title, id] = (router.query.params || []) as routerParam;
return (
<div>
<h4>{title}</h4>
</div>
);
}
- 초기값 빈 배열을 설정해 주어야 한다.
3-5) SSR (Server Side Rendering)로 백엔드에서 받아온 param 정보를 넘겨주는 방법.
* 공식 문서 *
https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props#getserversideprops-with-typescript
import { GetServerSideProps, InferGetServerSidePropsType } from "next";
import { NextRouter, useRouter } from "next/router";
import { ParsedUrlQuery } from "querystring";
type routerParam = [string, string];
export default function Detail({
params,
}: InferGetServerSidePropsType<typeof getServerSideProps>) {
const [title, id] = (params || []) as routerParam;
return (
<div>
<h4>{title}</h4>
</div>
);
}
interface IServerParams extends ParsedUrlQuery {
params: string;
}
export const getServerSideProps: GetServerSideProps = async (context) => {
const params = context.params as IServerParams;
return {
props: params,
};
};
- API 요청이 아닌 단순 페이지 이동이기 때문에 느려질 가능성은 거의 없다.
반응형
'React' 카테고리의 다른 글
[NextJS] redirect, rewrites, getServerSideProps을 사용한 URL 마스킹 방법 (0) | 2022.10.17 |
---|---|
[NextJS] Style JSX, Custom App Component( _app 파일), SEO(검색 엔진 최적화) 사용 방법 (0) | 2022.10.14 |
[NextJS] 프로젝트 생성 및 실행 방법 (0) | 2022.10.12 |
[NextJS] Pre-Rendering, Client-Side-Rendering, Server-Side-Rendering 개념 (0) | 2022.10.11 |
[React] Framer Motion(5) Share Layout Animation를 사용한 애니메이션 효과 공유 (0) | 2022.10.03 |