【React】Reactのstateを学びながら星評価を作ろう！！

# 【React】Reactのstateを学びながら星評価を作ろう！！

## はじめに
この記事は初学者が学びながらアウトプットとして残している記事になります。
同じところで詰まった方の力に少しでもなれればいいなと思います。
何度か練習でReactで簡単なアプリ作成していたのでサクッとcreate-react-appで作成した上で実行しています。

実行環境
- M1 Mac
- node v16.15.0

## ディレクトリ
今回はサクッと動作確認できればと思ったので、下記のようにsrcに全てそのまま入れ込んでいます。ここからcomponentディレクトリに入れ使いやすく自身でしていただければと思います。
```
create-react-app
    ├ node_modules
    ├ public
    └  src
       ├ Star.js
       ├ StarRating.js
       └ index.js
```

## 作成準備
まず今回作成したものはReactハンズオンラーニングの6章ステート管理の部分になります。
create-react-appで雛形作成していただき次に今回使用する星のアイコンの準備で下記を実施ください。
様々なアイコンが使えるようになるライブラリになります。
```
npm i react-icons
```
その後、ディレクトリ構成のようにStar.jsファイルとStarRating.jsを作成ください。

## とりあえず星を表示してみる
まずインストールしたアイコンを使用し星を表示させます。 
先ほど作成したStarRatingファイルに下記を記述してください。
import { FaStar } from "react-icons/fa"この部分が先ほどインストールしたライブラリの読み込みになります。
```javascript:StarRating.js
import React from "react";
import { FaStar } from "react-icons/fa";

export default function StarRating() {
  return [
    <FaStar color="red" />,
    <FaStar color="red" />,
    <FaStar color="red" />,
    <FaStar color="grey" />,
    <FaStar color="grey" />
  ];
}
```

記述できましたら、index.jsに下記の様に追記してStarRatingファイルを読み込みます。
そしてroot.render以降に記述のあるAppをStarRatingに変更してください。
```javascript:index.js
import StarRating from './StarRating';
```
![スクリーンショット 2023-05-14 20.34.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741017/8c9ae2a6-2231-9eb4-c4d6-b6ae2f9f7c69.png)
npm startすると下記のような星マークが出ているかと思います！

## Stateを使い星の状態を管理する
それではまずこの星が動かせる様になる状態にします。

### StarRating.js
```javascript:StarRating.js
import React, {useState} from "react";
import { Star } from "./Star";

export default function StarRating({ totalStars = 5 }) {
  const [selectedStars, setSelectedStars] = useState(0);
  return (
    <>
      {[...Array(totalStars)].map((n, i) => (
        <Star
          key={i}
          selected={selectedStars > i}
          onSelect={() => setSelectedStars(i + 1)}
        />
      ))}
      <p>
        {selectedStars} of {totalStars} stars
      </p>
    </>
  );
}
```

### Star.js
```javascript:Star.js
import { FaStar } from "react-icons/fa";
import React from "react";

export const Star = ({selected = false, onSelect = f => f }) => {
  return(
    <FaStar color={selected ? "red" : "grey"} onClick={onSelect} />
  )
};

```
こちらを記載のファイルに記述していただければとりあえず簡易版星評価の完成です！
次で細かく何が行われているか見ていきます！

## StarRatingファイル説明
このファイルが今回のメインになります。下記の部分がまずstateの定義です。
selectedStarsが変数になりこの変数で星の状態を管理します。setSelectedStarsはselectedStarsの関数になります。命名は自由ですが、基本的に宣言した変数にsetをつけたものになります。デフォルトで0を指定しています。
```javascript:StarRating.js
const [selectedStars, setSelectedStars] = useState(0);
```

そして下記の部分ではtotalStars=5という引数を受け取っているのですがこの要素数に対して、[...Array(totalStars)].map((n, i)で一度展開し要素の数だけ星を生成しています。mapは中身を１つずつ取り出しながら繰り返し以降の処理を行なっていくものです。
その以降の処理として１つずつStarコンポーネントとして描画していきます。selected={selectedStars > i}は繰り返し処理でiより大きいかどうかの判断をします。
onSelect={() => setSelectedStars(i + 1)}ではクリックされた時にプラス１しています。

```javascript:StarRating.js
{[...Array(totalStars)].map((n, i) => (
  <Star
    key={i}
    selected={selectedStars > i}
    onSelect={() => setSelectedStars(i + 1)}
  />
))}
```

## Starファイル説明
このファイルでは先ほどのselectedとonSelectプロパティが追加されておりonClick={onSelect}はそのままクリックされたかどうかの判断部分になります。StarRatingで作成されるこのでここでpropsを受け取ります。selectedは受け取るとデフォルトは＝falseになっています。そして color={selected ? "red" : "grey"}で判断されます。A ? 　"" ： ""はAがtrueの時に：の左側を実行し、falseであれば：の右側を実行するものです。ここで色を分岐させています。
```javascript:Star.js
export const Star = ({selected = false, onSelect = f => f }) => (
  <FaStar color={selected ? "red" : "grey"} onClick={onSelect} />
);
```
この部分は=>以降のかっこに気をつけてください。何も考えずに進めていた私は{}を使っておりなんでreturnないんだと１０分ほど悩んでおりました、、、笑

これで完成です！！
![スクリーンショット 2023-05-14 21.24.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741017/4a684cca-9dfb-f344-0ee0-7ca65a4884cf.png)

## おわりに
最後まで見ていただきありがとうございました。
まだまだ初学者なので至らない点あればご教授いただけると幸いです。
現在は下記著書で学んでおり、今回の学びを記事としアウトプットさせていただきました。
下記リンクよりよければご購入ください！！

[Reactハンズオンラーニング第二版](https://www.amazon.co.jp/React%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E7%AC%AC2%E7%89%88-%E2%80%95Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA%E3%81%AE%E3%83%99%E3%82%B9%E3%83%88%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-Alex-Banks/dp/4873119383/ref=sr_1_1?adgrpid=128868800110&hvadid=655142911916&hvdev=c&hvlocphy=1009523&hvnetw=g&hvqmt=e&hvrand=3028760564601642788&hvtargid=kwd-1456077059957&hydadcr=27272_14669469&jp-ad-ap=0&keywords=react%E3%83%8F%E3%83%B3%E3%82%BA%E3%82%AA%E3%83%B3%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0+%E7%AC%AC2%E7%89%88&qid=1684067207&sr=8-1)