はじめに
今回のハンズオン勉強会ではレシピ一覧を表示するサンプルコードを用意しました。
Repository
モックサーバー、リスト表示コンポーネントが既に実装されているので、そこにRating機能を追加するといった内容のハンズオンを実施しました。
サンプルコードの実行方法
前提条件
- Git
- node.js ≧ v14
- npm
- @stoplight/prism-cli(入っていない場合は後の手順で導入)
ローカルにサンプルコードを落とす
以下のコマンドでGitからソースコードを落として、プロジェクトのディレクトリを移動、必要なパッケージのダウンロードまでをやってくれるので、コピペして各自のシェルで実行してください。
git clone https://github.com/koki-2424/react-hands-on-learn.git
cd react-hands-on-learn/client
npm i
プロジェクト構成については以下のようになっていますので、落としたプロジェクトをVS Code(各自のエディター)で開いてみてください。
C:\
|
|─client
| ├─App.jsx # 一番上にあるコンポーネント、ルーティングを実装
| ├─index.css
| ├─index.js # entry point for all node apps
│ ├─public
│ └─src
│ ├─api
│ ├─components # UIの部品、各ページで使いまわせるように設計するのが理想
│ └─pages # どのPageコンポーネントを呼ぶかはApp.jsxのpagesコンポーネントで定義している
└─server # モックサーバーを配置
└─data
モックサーバーの起動
モックサーバーを起動する。
@stoplight/prism-cliは入っていない人のみ実行
npm install -g @stoplight/prism-cli
npm run server
フロントエンドの起動
npm run start
Reactコンポーネント
以下のHelloは一番シンプルなReactコンポーネントです。
JSX式で書かれているため見慣れないかもしれませんが、これはシンプルなJavaScript関数です。
以下のHelloコンポーネントはプロパティとしてデータを渡しています。
Reactでは関数でいう引数のことをプロパティと呼び、これはRead onlyなデータとなります。
プロパティだけでは動的なデータをコンポーネントの中で扱うことができず、これだけでは実務で使えるアプリケーションの構築をすることはできません。
// 引数として渡されている"message"がプロパティ
function Hello({message}) {
return <div>{message}</div>
}
<Hello message="hello world!" />
それに対して、描画後に変更できるデータをステートと呼びます。
ステートを導入することで、よりインタラクティブなアプリケーションを構築することができるようになります。
※Reactでは他ファイルで使いたいコンポーネントがあるときは、export
してファイル外から呼び出し可能にして、import
することで他ファイルのコンポーネントを呼び出すことができます。サンプルコードにはexport
, import
の記述がありますが、深い意味はなく他ファイルから呼び出すための記述だと理解してください。
ステート管理
サンプルデータのvalue[n].rate
にRating機能のための数値データを用意しました。
このデータを使ってReactのステート管理の仕組みを試しましょう。
StarRatingコンポーネントを配置する
react-hands-on-learn\client\src\pages\RecipeList.jsx
で定義したStarRatingコンポーネントを使ってRating機能を実装する。
作成済のコードは星の色を固定値で書いているため、以下のように色を切り替えられるStarコンポーネントを新しく定義してください。
const Star = ({selected = false}) => (
<FaStar color={selected ? "yellow" : "grey"} />
)
上のように定義することでselectedプロパティの値によって異なる色の星を描画することができます。
レーティングのUIは星5であることが多いですが、Starコンポーネントを別に定義しておくことで星10で細かなレーティングをできるようにしたい。といった要求に答えられるようになります。
新しくStarコンポーネントを定義したのでStarRatingコンポーネントを以下のように書き換えてください。
function StarRating({totalStars = 5}){
return [...Array(totalStars)].map((_, i) => <Star key={i} />);
}
これで、デフォルトで5つの星を表示するコンポーネントが作成できました。
試しにRecipeListコンポーネントに配置してみてください。
useStateフックを使ってクリックイベントに対応する
関数コンポーネントでステートを実装する場合はReactが提供するフックという機能を使います。
今回の勉強会では関数コンポーネントについてしか触れていないのですが、Reactにはクラスコンポーネントとして定義する方法もあります。
クラスコンポーネントを使う場合は、フックではなくライフサイクルメソッドを使ってコンポーネントの状態管理を行います。
2019年2月のReactのアップデートがされてからは、クラスコンポーネントではなく、関数コンポーネントを使う方が主流になると考えられます。
ここではStarRatingコンポーネントにステートを追加したいのでuseStateというフックを使います。
以下のようにコードを書き換えてください。
import { useState } from 'react';
const Star = ({ selected = false, onSelect = f => f }) => (
<FaStar color={selected ? "yellow" : "grey"} onClick={onSelect} />
)
function StarRating({ totalStars = 5 }) {
// selectedStarsにはデフォルト値"0"がセットされる
// setSelectedStarsにはselectedStarsを更新するメソッドがセットされる
const [selectedStars, setSelectedStars] = useState(0);
return (
<>
<div className='flex'>
{[...Array(totalStars)].map((_, i) => (
<Star key={i}
selected={selectedStars > i}
onSelect={() => setSelectedStars(i + 1)} />
))}
</div>
<p>{selectedStars} of {totalStars} stars</p>
</>
)
}
export default StarRating;
上記のコードでは、StarコンポーネントにonSelectプロパティを追加しています。onSelectは関数で、そのままFaStarコンポーネントのonClickイベントのハンドラとして設定されています。
それにより、星のアイコンがクリックされたことを親コンポーネントへ伝えることができる。
上記の例ではuseState()の返り値が二つの変数に代入されている。
const [selectedStars, setSelectedStars] = useState(0);
この書き方はReactで頻繁にされるものででストラクチャリングと呼ばれている。
JavaScript Document: Destructuring assignment
RecipeListにRating機能を追加してください。
書き換える場所は以下です。
function List({ data = [], renderEmpty }) {
if (!data) return renderEmpty;
return (
<div>
{data.map((item, i) => (
<div class="max-w-md py-4 px-8 bg-white shadow-lg rounded-lg my-20">
<div>
<h2 class="text-gray-800 text-3xl font-semibold">{item.name}</h2>
<p class="mt-2 text-gray-600">{item.description}</p>
</div>
<div class="flex items-stretch">
<div className='flex-1 mt-4'><p>{item.rate}</p></div>
<div className='flex-1 text-right mt-4'>
<a href="#" class="text-xl font-medium text-indigo-500">Detail</a>
</div>
</div>
</div>
))}
</div>
);
}
参考文献
今回の勉強会は「Reactハンズオンラーニング」の内容をもとにしています。
本日は「Reactの基本」、「関数の作成」、「ステート管理」から30ページほどを抜き出して学習しました
本の構成としては以下のようになっていてJavaScriptの基礎から学べるので誰にでもおすすめな書籍です。
今回の勉強会で少しでも興味のある方は是非読んでみてください。
- Reactの全体像: 最初5ページ
- JavaScriptの基礎(関数型プログラミング, オブジェクト, 非同期処理...):約 1 / 6
- Reactの基本から環境構築まで:約 1 / 6ページ
- ステート管理、フック:約 1 / 3
- データ通信について:約 1 / 6
- Reactの将来、Reactライブラリについて:約 1/ 3
- サスペンス
- テスト
- ルーティング
- サーバーサイド
- Next.js,
Gatsby
- Next.js,