チュートリアル/3-フロントエンド
なにが目的なの
フロントエンドアプリ開発の流れを掴むこと
SPA (Single Page Application)とMPA(Multi Page Application)の実装上の違いを知ること
なにをするの
カウンターアプリを作るよ
https://scrapbox.io/files/60ee9be22576fc001cd79eff.png
使用技術は,Express.js,Next.js,Reactだよ
完成形は GitHub に載せてるよ
やっていくよ
0. バックエンドプログラムを用意する
フロントエンド用とは別のディレクトリで
ソースコードをダウンロード
依存パッケージをインストール
$ yarn install
バックエンドサーバを起動するとき
$ node app.js
1. フロントエンド環境構築
↑のバックエンド用とは別のディレクトリを用意する
プロジェクトの初期化
次の1, 2 のどちらかで環境構築する
チュートリアルでは 2の方法で解説するよ
1. create next-app を使う場合
$ yarn create next-app
2. 使わない場合
$ yarn init
実行するとpackage.jsonが作成される
以下のように Next.js プロジェクトを起動させる yarn scripts を追加する
code:json
{
"name": プロジェクト名,
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts":{
"dev":"next dev"
},
"dependencies": {
// 依存パッケージ
}
}
Next.js パッケージをインストール
$ yarn add next react react-dom
(Git を使う場合).gitignore ファイルを追加 code:.gitignore
node_modules
.next
2. 最初に表示されるページを作成する
pagesディレクトリを作成
Next.js ではpagesディレクトリ内の.jsxファイルがサイトのページになる
pagesディレクトリ内にindex.jsxを新規作成
index.jsx に処理とJSXを記述する
code:jsx
import { useCallback, useState } from "react";
const IndexPage = () => {
// count : カウントを保持する状態変数
// setCount : count の値を変更する関数
// 状態が変化したときに実行される処理
const increment = useCallback(() => setCount((x) => x + 1), []);
const decrement = useCallback(() => setCount((x) => x - 1), []);
// JSXを返す
return (
<div>
<h1>カウンター</h1>
<div>
<span>{count}</span>
</div>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<p>クライアント内だけでカウントが変わる</p>
</div>
);
};
export default IndexPage;
ちなみに useCallback()は
状態が変わるたびに関数が再定義されることを防ぐ役割がある
なくても動くけど,再定義されるからメモリ領域が無駄に圧迫されちゃう
サーバを起動してページを見てみる
$ yarn dev
カウンターアプリが表示され,ボタンクリックでカウントが変化したら成功!
3. バックエンドのAPIを叩く
pagesディレクトリ内にajax.jsx を新規作成する
ajax.jsx に処理とJSXを記述する
code:jsx
import { useState, useEffect } from "react";
const AjaxPage = () => {
// 状態が変わるたびに実行される
useEffect(() => {
// API サーバから count の値を取得する
fetch(${ApiBaseUrl}/count)
.then((response) => response.json())
.then(({ count: value }) => setCount(value));
}, []);
// API サーバに POST して count を increment する
const increment = () => {
fetch(${ApiBaseUrl}/count/increment, { method: "POST" })
.then((response) => response.json())
.then(({ count: value }) => setCount(value));
};
// API サーバに POST して count を decrement する
const decrement = () => {
fetch(${ApiBaseUrl}/count/decrement, { method: "POST" })
.then((response) => response.json())
.then(({ count: value }) => setCount(value));
};
if (count === undefined) {
return <p>よみこみちゅう…ちょっとまってね</p>;
}
return (
<div>
<h1>カウンター</h1>
<div>
<span>{count}</span>
</div>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
<p>サーバで保持するカウントも変わる</p>
</div>
);
};
export default AjaxPage;
AjaxPage コンポーネントでおこなっていること
APIサーバからのcountの取得
fetch(\`${ApiBaseUrl}/count\`)
APIサーバへの POST メ ソッド
fetch(\`${ApiBaseUrl}/count/decrement\`, { method: "POST" })
状態の保持
const [count, setCount] = useState(undefined);
DOMの描画
return (<div> ... </div>)
サーバを起動してページを見てみる
$ yarn dev
カウンターアプリが表示され,ボタンクリックでカウントが変化したら成功!
別タブでのカウントと共有されている!!!
サーバ側でカウントが保持されていることがわかる
完成!!!
おまけ
ページの全体像
localhost:4000/
Express 製
Hello World!
/
Multi Page Application カウンター
ボタンクリックするとページがリロードされる
<form> でPOST
/counter
/counter/increment
/counter/decrement
APIサーバ
/count/increment
/count/decrement
localhost:3000/
Next.js 製
クライアントだけで値変更のあるカウンター
/
全クライアントでカウントを共有するカウンター
/ajax
fetch()でPOST