はじめに
今回、ReactのプロジェクトをNext.jsにreplaceする機会があったので、忘備録として記録しました。
1. Next.jsのインストール
(前提)npx create-react-appにてReactプロジェクトを作成している場合
プロジェクト直下にて
yarn add next
2. ファイル構造を変更
以下のように変更。
frontend/
public/
- index.html
src/
...
+ pages/
+ _app.js
+ _document.js
+ (必要なページ分jsxファイルを作成する)
- index.js
- App.js
...
Reactでは、index.html -> index.js -> App.js と読み込まれるが、
Next.jsでは、
_app.js: 全ページで共通して実施させたい処理を記述
_document.js: 全体の文書構造をカスタマイズ
をベースとして、それぞれのPageが読み込まれる。
以下の記事参考にさせて頂きました。
https://qiita.com/tetsutaroendo/items/c7171286137d963cdecf
ルーティングはpagesのファイル構造を反映する。
pages/
_app.js
_document.js
index.jsx
login.jsx
users/
index.jsx
[id].jsx
上記のファイル構造の場合、以下のルーティングになる。
/ (ルートパス) => index.jsx
/login => login.jsx
/users => users/index.jsx
/users/:id => users/[id].jsx
3.Next.jsのLinkコンポーネントに置き換える
既にreact-route-domでのLinkコンポーネントを使っている場合、
next.jsのLinkコンポーネントに置き換える。
import Link from 'next/Link'
Linkコンポーネントは以下の様に書く。
<Link href='/users'><a>ユーザー</a></Link>
これによりClient Side Navigationが実現できる。
(JavaScriptによってページを切り替える仕組み。ページの再読み込みが不要。クライアントの状態を保ってページ遷移。)
また、ページにLinkコンポーネントがある場合、そのLink先のコードを事前に取得(prefetch)する。
4.CSSを反映させる
styled-component
パッケージを追加。
yarn add -D babel-plugin-styled-components
プロジェクト直下に以下のファイルを作成。
{
"presets": [
"next/babel"
],
"plugins": [
[
"styled-components",
{
"ssr": true,
"displayName": true
}
]
]
}
@material-ui/core/styles
_document.jsのgetServerSidePropsを以下のように記述。
import React from "react";
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { ServerStyleSheets } from "@material-ui/core/styles";
import CssBaseline from '@material-ui/core/CssBaseline'
const MyDocument = () => {
return (
<Html>
<Head />
<body className="custom_class">
<CssBaseline/>
<Main />
<NextScript />
</body>
</Html>
)
}
MyDocument.getServerSideProps = async (ctx) => {
const sheets= new ServerStyleSheets();
const originalRenderPage= ctx.renderPage;
ctx.renderPage = () => originalRenderPage({
enhanceApp: (App)=> (props)=> sheets.collect(<App {...props} />)
});
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement()
]
}
}
export default MyDocument
5. 環境変数を.envにて管理している場合
クライアントサイドで使用するには定義する変数名のプレフィックスにNEXT_PUBLIC_をつける。
NEXT_PUBLIC_REACT_APP_GO_API_URL=http://localhost:8080
以下のように呼び出せる。
process.env.NEXT_PUBLIC_REACT_APP_GO_API_URL