Next.jsのチュートリアルをよむ
2019/2/16
チュートリアルをおえた感想

Getting Started
Syntax errorがブラウザに出る
HMRがデフォルトでサポートされている(Webpackを使っている)
Navigate Between Pages
ページ遷移したいときはLink APIを使う
pageを作りたいときにはpagesディレクトリにコンポーネントを作成してexport defaultする
このディレクトリは唯一、名前を変えることはできない(他のディレクトリは任意の名前をつけることができる)
ファイル名がURLになる。 pages/about.js
なら /about
でその内容を表示する
a
タグ使えるけどサーバーサイド経由でnavigateされてクライアントサイドでnavigateされない
Linkを使うとサーバサイドにリクエストがいかない
ページ中のリンクはLink APIで実装されている。このときNetworkの通信ログがない
Backボタンを押したら履歴が残っていて、戻る(サーバにリクエストも飛ばない)
next/link
は"href"などしかうけとらない
HOCだからstyleはあたらない
js <Link href="/about">
<button>Go to About Page</button>
</Link>
のように onClick
propが使えるものは何でも子要素にできる
Using Shared Components
この章でやること
共通Headerをつくって複数のページから利用する
Layout componentで複数のページのレイアウトを決める
componentsディレクトリにコンポーネントを作成していろんなページで読み込める
HeaderをつくったりLayoutをつくったりできる
ここまでで複数ページをどうつくるか理解できている
Create Dynamic Pages
ブログアプリで動的にページを作っていく例
モチベーション
ページを作るためにはディスクに実態をつくらないといけないが、動的なコンテンツを表示するために動的にページが作りたい時がある
方法:Next.jsではいくつか方法がある。query stringsを使うのからはじめる
<Link href={
/post?title=${props.title} }>
のようにqueryを指定できる
/post
で pages/post.js
にpropsを渡すことができる
post.js
では withRouter()
の中では props.router.query
でクエリパラメータが取得できる
まだできないこと
/blog/lhello-nextjs
のようなURLを与えたい
すべてのquery stringでレンダリングに必要な情報のすべてを渡す
Clean URLs with Route Masking
できること: 実際のURLではない URLをブラウザに表示する
これが http://localhost:3000/post?title=Hello%20Next.js
こうなる http://localhost:3000/p/hello-nextjs
as
を使うとブラウザに示すURLを指定できる
<Link as={
/p/${props.id} } href={
/post?title=${props.title} }>
問題
実際にみているのは hello-nextjs
ではないので、その状態でリロードするとサーバにリクエストがとんで404になる
解決策
この問題はcustom server APIを使うことで解決できる
Server Side Support for Clean URLs
custom server APIをつかって、前節の、リロード時に404になる問題を解決する
Expressでcustom serverをたてて設定を書く
/p/:id
でアクセスされたらclient sideでレンダリングしたものと同じページを出すようにする
注意:npm run devをやりなおさないとserver.jsの内容は反映されない
とはいえQuery Stringでもらったような情報がもらえないので、内容が変わってしまう
理由:リロードしたときのサーバへのリクエストにはタイトル情報は含まれないので、同じページが出せない
js server.get('/p/:id', (req, res) => {
const actualPage = '/post'
const queryParams = { title: req.params.id } // 仕方なくtitleをidにしている
app.render(req, res, actualPage, queryParams)
})
現実に問題になることは少ない。理由
>But in the real world, this won't be much of an issue because we'll use an ID to fetch data from a data server in both client and the server.
Fetching Data for Pages
外部のAPIをたたいてpagesにもってくるようなしくみを提供している
getInitialProps()
を使うとページにAPI渡した結果のpropsをわたせる
server/clientどちらでも使える
直接アクセスした場合はserverで getItinialProps()
がよばれるし、client sideで遷移した場合にはclient sideでよばれる
server.js server.get('/p/:id', (req, res) => {
const actualPage = '/post'
const queryParams = { id: req.params.id }
app.render(req, res, actualPage, queryParams) // serverがpageを呼んで、その中でinitializeされる
})
nextにおけるfetchをもっと知りたいなら
Styling Components
Reactアプリ一般の方法
従来の方法(SASS, PostCSSなど)
様々な問題がある。特にSSRで
Next.jsでは非推奨
推奨
他にも方法がある
js<style jsx>{`
// ここにCSSをかける
h1 { }
`}</style>
styleは子コンポーネントには適用されない
globalにstyleをあてたいときがある
例えばmarkdownを使うときとか
js <div className="markdown">
<Markdown source={`
This is our blog post.
Yes. We can have a [link](/link).
### This is a title
And here's the content.
`}/>
</div>
<style jsx global>{` // global scopeになった
// ここにstyleをかくと子コンポーネントの<Markdown>にもstyleがでてきようされる
'}</style>
prefixingとかvalidationは
babelの中で行われるので追加のオーバーヘッドはない
Deploying a Next.js App
複数インスタンスを実行する
PORT=8000 npm run start
とかでポートを指定して複数実行できる
Export into a Static HTML App
next export
で /out
にはかれる
HTMLのexporutを行うためには事前の設定が必要(この設定がすべてを司っている)
next.config.jsmodule.exports = {
exportPathMap: function () {
return {
'/': { page: '/' }
}
}
}
こうすると/がexportされて、ナビゲーションはClient sideで適切にJSがロードされる
課題:直接URLにacccessしても404になる
理由:表示されているようなHTMLのページはホストされていないから。clientが適切なJS(ページを表示するpost.js)をロードしているだけ
次のようなconfigを書くことによって直接アクセスが可能になる
next.config.js // このページにアクセスされたら :{page: 'このページのJSに', query: {'このQueryを投げる'} }
'/p/hello-nextjs': {page: '/post', query: {title: 'Hello Next.js'}},
'/p/learn-nextjs': {page: '/post', query: {title: 'Learn Next.js is awesome'}},
'/p/deploy-nextjs': {page: '/post', query: {title: 'Deploy apps with Zeit'}}
この場合、設定にpageを追加してもbuildし直す必要はない(pageはすでbuildされているため)
この方法が使えないケース
デプロイ後にpagesをdynamicに生成したい場合
next start
でnode上にホストするか、
APIを使う