初めてのフロントエンド開発~機能実装編~

# はじめに
　皆さんお疲れ様です！レイアウト編何とかなったでしょうか？前回、前々回の記事を行っていない方は是非やってみてください。
 
- 前回の記事

https://qiita.com/Semikoron/private/ca3c4642dbf1bd6975d1

- 前々回の記事

https://qiita.com/Semikoron/private/2f09e4fc3c2d12c14b12

　今からはフロントエンドとバックエンドをつなぐ作業を行います。私たちが用意した表示するためのコードにバックエンドに用意してもらったデータを表示する事を目標に頑張りましょう！
 　最終的な目標は、商品を検索し、その検索結果を表示できるようにしましょう。

## まずは入力欄から
　最初に入力できる場所を作りましょう。
```tsx:input
      <input
        type="search"
        onChange={handleChange}
        placeholder="検索ワードを入力"
      />
```
これはinputタグと言い、Webサイト上の入力するものはこのinputタグが使われています。type、onChange、placeholderそれぞれの属性についても説明していきます。

### type属性
typeはinputする形を選択することができます。詳しい説明は省きますが、このtype属性によってカラーコードを入力するところや、日付を入力するところを作ることができます。

### onChange属性
onChange属性は属性に入れられた関数をinputの中身が変わるたび(入力、削除のたび)実行してくれる属性です。関数を簡単に説明すると、あらかじめ設定しておいたプログラムの命令を関数名でセットとしてまとめられるとても便利なものと認識してください。
今回はhandleChangeという関数が実行されるようになっていますね。

### placeholder属性
placeholder属性はinputに何も入力されていないときに表示される言葉です。Googleの検索するときに書いてある「Google で検索または URL を入力」ですね。

### コードを組み込んでみる
では以下のようにコードを編集してみてください
```diff_tsx:page.tsx
"use client";
import { useState } from "react";
import { Hit } from "./dataType";
import { testData } from "./testData";
import styles from "./page.module.css";

export default function Home() {
  const [searchResult, setSearchResult] = useState<Hit[]>(testData);
+  const [searchWord, setSearchWord] = useState("");

+  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
+    setSearchWord(e.target.value);
+  };

  return (
    <>
+      <input
+        type="search"
+        onChange={handleChange}
+        placeholder="検索ワードを入力"
+      />
      {searchResult.map((item: Hit) => (
        <div key={item.index}>
            [前回書いたコード]
        </div>
      ))}
    </>
  );
}

```
このように入力してみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620008/bd65eeca-f6bc-e080-7971-8fbfb68c359f.png)
検索ワード入力欄が現れましたね！ﾔｯﾀｰ‼
さて検索ワードが入力できたら次やることは検索ボタンのクリックです！
ではボタンを作っていきましょう！

## 検索ボタンを実装していく

検索にはbuttonタグを使います。
```tsx:butto
<button onClick={search}>検索</button>
```
buttonタグはいつも通りの使い方で間に挟んだものをボタンの文字として表示することができます。
またonClick属性はonChangeと似たような働きで、クリックされたときに割り当てられた関数を実行するという属性です。今回はsearch関数が実行されるということが分かりますね。
ではコードを編集していきましょう。

```diff_tsx:page.tsx
"use client";
import { useState } from "react";
import { Hit } from "./dataType";
import { testData } from "./testData";
import styles from "./page.module.css";

export default function Home() {
  const [searchWord, setSearchWord] = useState("");
  const [searchResult, setSearchResult] = useState<Hit[]>(testData);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchWord(e.target.value);
  };

+  const search = async () => {
+    console.log(searchWord);
+  };

  return (
    <>
      <input
        type="search"
        onChange={handleChange}
        placeholder="検索ワードを入力"
      />
+      <button onClick={search}>検索</button>
      {searchResult.map((item: any) => (
        <div key={item.itemId}>
          <img src={item.image.small} />
          <div>{item.name}</div>
          <div>{item.price}円</div>
        </div>
      ))}
    </>
  );
}
```
このように編集してみると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620008/b729edd1-65a0-b17f-a122-29acacd7f475.png)
しっかりとボタンが現れてくれました！
では次に検索ワードを入れてボタンを押してみましょう。
皆さん適当なワードを入れて検索してみてください！

すごいことに何も起こりません！おいここまでやったのは無駄だったのか？この野郎！？と言いたい気持ちは分かります。ですがWebフロントそう簡単には上手くいきません。
では皆さんブラウザ上の画面で検証ツールを使ってみましょう。画面を右クリックを押してメニューから「検証」を選択、もしくはF12キーを押して検証画面を開きましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620008/a16a6566-6317-2c9b-d075-6b88ce126284.png)
なんだ？この画面と思うかもしれませんが、フロントエンジニアは毎日この画面を見ます。(多分)

ではでは次にConsoleを選んでコンソール画面を開いてみましょう。
![スクリーンショット 2024-06-22 175357.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620008/9e36fb6f-c2f7-a68e-54dd-6236aa214875.png)
コンソール画面を開くことができたらログを見てみましょう。
ログを見てみると先ほどの検索ワードが表示されているのがわかりますね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620008/00eae676-2ce8-e7f4-105c-abc67d0a8a13.png)
このことはsearch、handleChange関数がしっかり機能していることを意味します。
では次にsearch関数の中に検索ワードを通信するコード、受け取ったデータを表示する変数に代入するコードを書いていきます。

以下のように編集してみてください。

**※全体公開後から見てくださった皆様へ**
この下のコードのURLの部分は直接yahoo APIを叩いているのではなく、CORSエラーを出さないためにAzure functionsのhttpトリガーを用いて間接的にyahoo APIを叩いています。このAPIを叩く機能実装を作製する際の参考にしてください。またCORS全く分からないので、もっとスマートな方法があれば、教えて頂ください。

```diff_tsx:page.tsx
"use client";
import { useState } from "react";
import { Hit } from "./dataType";
import { testData } from "./testData";
import styles from "./page.module.css";

export default function Home() {
  const [searchWord, setSearchWord] = useState("");
  const [searchResult, setSearchResult] = useState<Hit[]>(testData);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchWord(e.target.value);
  };

  const search = async () => {
    console.log(searchWord);
+    const reqURL = //対面の時に教えてもらってね！！
+    const response = await fetch(reqURL);
+    const data = await response.json();
+    setSearchResult(data.hits);
  };

  return (
    <>
      <input
        type="search"
        onChange={handleChange}
        placeholder="検索ワードを入力"
      />
      <button onClick={search}>検索</button>
      {searchResult.map((item: Hit) => (
        <div key={item.index}>
          <img src={item.image.small} />
          <div>{item.name}</div>
          <div>{item.price}円</div>
        </div>
      ))}
    </>
  );
}
```
さて、動作はするでしょうか、
皆さんも自分の画面で検索を行ってみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3620008/3334f7af-8a87-1a4b-8203-331188af8088.png)
検索できたぞ！ﾔｯﾀｰ‼

これにて機能実装編は終了です！お疲れ様でした！
これが終わったころ時間、皆さんに余裕がありそうであれば、CSS編をオフラインで行おうと思っております！まだここ分からないよ～とかここをもっと詳しく！などあればメンターさんや私を呼んでくださいね！