Next.js (2): Routing / App Component
Routing
Link
a タグのhrefを利用するとESlintでエラーになります。この方法だとページをリロードさせるので遅くなるからという警告してくれています。
aタグにhrefを利用しないで<Link>で囲む形で使います。
LinkにclassNameなどは使えないため、下位の<a>タグに入れます。
import Link from "next/link";
export default function NavBar() {
return (
<nav>
<Link href="/">
<a className='hello'>HOME</a> // a tagに追加
</Link>
<Link href="/about">
<a>About</a>
</Link>
</nav>
);
}
useRouter hook
https://nextjs.org/docs/api-reference/next/router
routerオブジェクトにアクセスするためのhookです。
例えばrouter.pathnameを使うと、現在の場所が取得できます。
以下のソースコードはpathnameを確認してlinkの色を変えています。
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 === "/about" ? "red" : "blue" }}>
About
</a>
</Link>
</nav>
);
}
aboutページに行くとnavのAboutリンクは赤く、HOMEリンクは青くしています。
App Component
https://nextjs.org/docs/advanced-features/custom-app
メイン画面とabout画面にヘッダーのようなnavigation barを表示したい場合、メイン画面とabout画面の両componentにnavigation componentを追加する必要はありません。
Next.jsはApp componentを利用してページの初期化していますが、_app.jsはそれを上書きできるcomponentです。pages/_app.jsを以下の内容で作成します。
ファイル名は_appにする必要があるが、component名は自由につけて大丈夫です。
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
export default MyApp
そしてNavBar componentとglobalなcssも追加してみました。これで全ページに反映されます。
他のcomponentを呼び出すときに、_app.jsに書いてあるのも追加でreturnしてあげる仕組みです。
import NavBar from "../components/NavBar";
import "../styles/globals.css";
export default function MyApp({ Component, pageProps }) {
return (
<>
<NavBar />
<Component {...pageProps} />
<style jsx global>{`
a {
color: lime;
}
`}</style>
</>
);
}
Dynamic Router
movies/123123 のようにid(ここだと映画のid)によって詳細ページに遷移させたい場合、idをファイル名にすることで渡せます。[]で囲む必要があります。
- 例)pages/movies/[id].js
import { useRouter } from "next/router";
export default function Detail() {
const router = useRouter();
console.log(router);
return "detail";
}
routerの中にqueryとして渡したidが入っています。
- query: id :'1'
[hoge]でファイル名を作った場合、hogeがkeyになります。
- 例) {hoge:123123}
useRouter.push
useRouter.push(url , as?:url)
routerのpushを使うと、上記のqueryを利用してurlでコンポーネントにパラメータを渡すことができます。
一番目の引数にはpathnameを使って遷移したいurlを書き、渡したいパラメータをqueryに書きます。
以下の例でonclickを発動させたときに、
import { useRouter } from "next/router";
const router = useRouter();
const onClick = (id, title) => {
router.push(
{
pathname: `/movies/${id}`, // 引数1
query: {
title,
},
},
);
};
// 省略
このようなURLに遷移されます。
http://localhost:3001/movies/634649?id=634649&title=spiderman
ここでurlをもっと綺麗にしたい場合にrouterのpushの引数2を使い、遷移させたいurlを書きます。
以下の例だと
import { useRouter } from "next/router";
const router = useRouter();
const onClick = (id, title) => {
router.push(
{
pathname: `/movies/${id}`,
query: {
title,
},
},
`/movies/${id}` //引数2
);
};
// 省略
このようなURLになります
http://localhost:3001/movies/634649
onClickして遷移されるページは以下のようにかけます。router.queryの中にidとtitleを受け取れます。
import { useRouter } from "next/router";
export default function Detail() {
const router = useRouter();
return (
<div>
<h4>{router.query.title}</h4>
</div>
);
}
Discussion