generated at
Next.jsのチュートリアルをよむ
from Next.js

2019/2/16

チュートリアルをおえた感想kadoyau
一回失敗させて理由を説明するスタイルが良い

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を使うことで解決できる
React Routerだとサーバ実装なしに勝手にやってくれるときいたのできになっているkadoyaukadoyau


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では非推奨
推奨
next.jsをつかうとstyled-jsxがpreloadされる
他にも方法がある
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
複数インスタンスを実行する
package.json
"scripts": { "start": "next start -p $PORT" }
PORT=8000 npm run start とかでポートを指定して複数実行できる
ZEITにデプロイする方法

Export into a Static HTML App
next export /out にはかれる
HTMLのexporutを行うためには事前の設定が必要(この設定がすべてを司っている)
next.config.js
module.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を使う