Open5

【Next.js】TypeScriptを使ったアプリケーションの実装

Yuki YukiYuki Yuki

Debug方法

  • package.jsondev部分を下記にUpdate
"dev": "NODE_OPTIONS='--inspect' next dev"
  • npm run devで起動
    下記のようにDebugger listening onと表示が出る
Debugger listening on ws://127.0.0.1:9229/0cf90313-350d-4466-a748-cd60f4e47c95
For help, see: https://nodejs.org/en/docs/inspector
ready - started server on http://localhost:3000
  • Chromeを開き、chrome://inspectへアクセス

  • アプリケーションを起動している場合、下記のようにRemote Targetに出てくるので、inspectを押す

  • 下記のようなでバックスクリーンが出てくる。(デバックの準備完了)

  • vsCodeに戻り.vscode/launch.jsonファイルを作成し下記、を設定する。

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Launch Program",
      "skipFiles": ["<node_internals>/**"],
      "port": 9229
    }
  ]
}
  • あとはデバッグポイントをvsCodeで設定し、F5ボタンでデバッグを行う。
Yuki YukiYuki Yuki

OpenAPI起動方法

$ docker run --rm -it -p 8080:4010 -v $PWD:/tmp stoplight/prism:4 mock -h 0.0.0.0 -d /tmp/openapi.yaml
Yuki YukiYuki Yuki

動的ルーティング対応の対応時期

※下記以前の記事を読む場合は注意!

  • リリース日: 2019/07/08
  • Version: 9.0.0

next/link

Linkの基本

Linkコンポーネントで<a>を子コンポーネントに配置し、propsのhrefで遷移したいURLを渡すことで、同じNext.jsプロジェクト内の他ページへ遷移が可能。
※propsのasはVersion9.5.3まで動的ルーティングの際にブラウザ上にURLをどう表示するかを定めるために設定していた。Version9.5.3はデフォルトで設定されるため、propsに設定しなくて良い。

  <Link href="/posts/first-post">
    <a>this page!</a>
  </Link>

加えて、<a>以外を子コンポーネントに配置することも可能。
※ページ遷移自体はできるが、別タブで開くことができなかったり、ブラウザがリンクとして認識しないなどの挙動になる。

  <Link href="/posts/first-post">
    <div>this page!</div>
  </Link>

独自コンポーネントを配置

Linkコンポーネントの子コンポーネントとして独自のコンポーネントを配置することも可能。
独自コンポーネントを配置する場合、Linkコンポーネントのprops としてpassHrefを設定が必要!

子コンポーネントが<a>をラップしたコンポーネントの場合

Linkコンポーネントのprops としてpassHrefを設定する必要がある。
※設定しないとブラウザがリンクとして認識しない

import Link from 'next/link'
import styled from 'styled-components'

// `<a>`をラップしたコンポーネントを作成する
const RedLink = styled.a`
  color: red;
`

function NavLink({ href, name }) {
  // passHrefは必須
  return (
    <Link href={href} passHref>
      <RedLink>{name}</RedLink>
    </Link>
  )
}

export default NavLink

子コンポーネントがfunction componentの場合

Linkコンポーネントのprops としてpassHrefを設定する必要がある。
また、forwardRef を通してref を受け渡し、Props(onClick, ref)を 子要素のaタグ 要素へ渡す必要がある。

import Link from 'next/link'

// props(onClick, href)とhrefをaタグに渡す
const MyButton = React.forwardRef(({ onClick, href }, ref) => {
  return (
    <a href={href} onClick={onClick} ref={ref}>
      Click Me
    </a>
  )
})

function Home() {
  return (
    <Link href="/about" passHref>
      <MyButton />
    </Link>
  )
}

export default Home

Linkコンポーネントの仕組みは下記がわかりやすかったです。

Link コンポーネントを利用すると、基本的には onClick によるクリックイベント発火時にHistory APIを用いてページ遷移が行われます。この際、Webブラウザのネイティブページ遷移は用いられず、また href 属性の値も利用されることはありません。そのため a 以外の要素でも、要素クリック時にページ遷移が可能になるわけです。
【Next.js 4年目の知見:SSRはもう古い、VercelにAPIサーバを置くな】(https://qiita.com/jagaapple/items/faf125e28f8c2860269c#6-link-で正しくリンクを貼る方法を知る)

Yuki YukiYuki Yuki

next/router

useRouter

routerobject(pathやqueryの情報や、画面遷移のメソッドを持っている)にアクセスするためのReact Hook
Linkコンポーネントが使えないFunctionの中で画面遷移したい時などに使用するイメージ。

import { useRouter } from 'next/router'

function ActiveLink({ children, href }) {
  // router objectを生成
  const router = useRouter()
  const style = {
    marginRight: 10,
    color: router.pathname === href ? 'red' : 'black',
  }

  const handleClick = (e) => {
    e.preventDefault()
    // コンポーネント型を返却しない、Functionの中ではLinkコンポーネントが使えない
    // そのうような時に、routerのメソッドを使って画面遷移を行う
    router.push(href)
  }

  return (
    <a href={href} onClick={handleClick} style={style}>
      {children}
    </a>
  )
}

export default ActiveLink

router.push

引数のurlに画面遷移する。

router.push('/posts')