React 繰り返し処理を利用してセレクトボックスを実装する

# 成果物
今回は`map`を利用してセレクトボックスを実装していきます。
セレクトボックスで選んだ値を「現在選択されている値」として表示し、その値に対応するハイパーリンクを作成します。
作成されたハイパーリンクをクリックすると、Wikiに画面遷移します。

https://codesandbox.io/embed/serekutobotan-arenzi-sldpol?fontsize=14&hidenavigation=1&theme=dark

# JavaScriptの文と式
JavaScriptは`文(Statement)`と`式(Expression)`から構成される
式(Expression)は評価値(式を評価した結果の値)を返し、得られた評価値を変数に代入できるものを指す。
例) 論理演算子、三項演算子等

文(Statement)は処理するステップのことを指しており、文末は`;(セミコロン)`で区切る。
例) if文、for文等（上から処理していくことでプログラムが実行される）

式は値を返しますが、文は値を返しません。

# コード
## index.js
```javascript
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";

import App from "./App";

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(
  <StrictMode>
    <App />
  </StrictMode>
);
```

## App.js
```javascript
import React, { useState } from "react";
import "./styles.css";

// セレクトボックスにセットしたい項目の配列 items を作成します
const items = [
  { id: 1, item: "リンゴ" },
  { id: 2, item: "イチゴ" },
  { id: 3, item: "メロン" }
];

// ハイパーリンクの共通部分
const link = "https://ja.wikipedia.org/wiki/";

// map（）で配列itemsから要素を1つずつ取り出し、各要素をoptionタグに設定していきます
const SelectItems = items.map((item) => {
  return (

    // value:選択された際に渡される値
    // key:optionタグ内で一意になる値
    <option value={item.item} key={item.id}>
      {item.item}
    </option>
  );
});

const InputSelectBox = () => {

  // 現在セレクトボックスで選択されているチェックボックスの状態変数 selectedValue 
  // selectedValue の状態を更新する関数 setSelectedValue
  // 初期値にはitems[0].item = リンゴ を設定する
  const [selectedValue, setSelectedValue] = useState(items[0].item);

  // 現在セレクトボックスで選択されている値に対応するハイパーリンクの状態変数 selectedLink 
  // selectedLink の状態を更新する関数 setSelectedValue
  // 初期値にはリンクの共通部分とselectedValueの初期値（items[0].item = リンゴ）を結合した
  // https://ja.wikipedia.org/wiki/リンゴ を設定する
  const [selectedLink, setSelectedLink] = useState(link + selectedValue);

  // セレクトボックスの値が変更された際に実行される
  const handleChange = (e) => {
    
    // セレクトボックスで選択された値(value)を状態変数（selectedValue）に設定する
    setSelectedValue(e.target.value);
  };

  // ハイパーリンクが押された際に実行される
  const handleLink = () => {

    // セレクトボックスで選択された値 selectedValue とリンクの共通部分 link を結合した値を
    // 状態変数（selectedLink）に設定する
    setSelectedLink(link + selectedValue);
  };

  return (
    <div className="App">
      <p>
        // 現在セレクトボックスで選択されている値が設定する
        現在選択されている値:<b>{selectedValue}</b>
      </p>

      // selectタグを設定する
      // セレクトボックスで値を選択すると関数 handleChange が実行される
      <select onChange={handleChange}>
        {SelectItems}
      </select>

      // ハイパーリンクをクリックすると関数 handleLink が実行される
      // 関数 handleLink の処理により更新され値 selectedLink をリンクとして設定する
      <a href={selectedLink} onClick={handleLink}>
        {selectedValue}のリンク
      </a>
    </div>
  );
};

export default function App() {
  return <InputSelectBox />;
}
```

## styles.css
```css
a {
  display: block;
}
```

# あとがき

当初のコードでは、セレクトボックスの値が変更された際に実行される関数`handleChange`とハイパーリンクが押された際に実行される関数`handleLink`を以下のように1つにまとめていました。

```App.js
  // セレクトボックスの値が変更された際に実行される
  const handleChange = (e) => {
    
    // セレクトボックスで選択された値(value)を状態変数（selectedValue）に設定する
    setSelectedValue(e.target.value);

    // 上の setSelectedValue によって変更された selectedValue を利用してハイパーリンクを設定する
    setSelectedLink(link + selectedValue);
  };
```

上記のようなコードにすると、`setSelectedValue(e.target.value);`で変更された値は`setSelectedLink(link + selectedValue);`では変更されておらず、値は更新されていませんでした。

例えば、セレクトボックスでリンゴからイチゴに値を変更した場合、`setSelectedValue（e.target.value）`により、状態変数`selectedValue`にはイチゴが設定されているが、`setSelectedLink(link + selectedValue)`により`selectedLink`に設定される値はhttps://ja.wikipedia.org/wiki/イチゴ ではなく、https://ja.wikipedia.org/wiki/リンゴ のままである。
よって、関数コンポーネントが終了するまで、useStateの値は変更されないことが確認できた。