ChatGPTと一緒にReactを勉強した

# はじめに
Reactの勉強をしたいなと思い、少しだけ触っては、何をしたらいいのか分からなくなり、1時間弱くらいでやめるといったことを繰り返していた、React初心者です。

勉強したいと思ってはいますが、あまり続かないので、ChatGPTに課題を出してもらい、それをこなす勉強を試してみました。
 
前々から、そういったChatGPTの使い方は、色々なところで見聞きしましたが、実際に自分でやってみたことはなかったので、今回のReactの勉強をきっかけに、使ってみようと思いました。

# 課題1
早速、まずは簡単な課題を出してもらいます。
![スクリーンショット 2024-11-24 180333.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/d549bcb2-397f-8ef1-4d34-957f302f9364.png)

![スクリーンショット 2024-11-24 180413.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/8a024f36-07c7-c130-439a-dab19d9e4f69.png)


だとのことなので、早速countプロジェクトを作成し、作ってみました。
 
途中、reactのことを覚えてなさ過ぎて、propsの使い方や、子から親への値の渡し方など、調べたりしました。
今回は自分で調べましたが、こういった分からないところも、その場でChatGPTに聞いたりしていいかもしれません。

そして、できたのが以下のコード。
```App.js
import './App.css';
import { useState } from 'react';

function App() {
  const [ count, setCount ] = useState(0);
  const handleCount = (number) => {
    setCount(number);
  };
  return (
    <div className='App'>
      <View count={ count }/>
      <CountButton count={ count } handleCount={ handleCount }/>
    </div>
  );
}

function View(props) {
  return (
    <div className='view'>
      {props.count}
    </div>
  );
}


function CountButton(props) {
  // カウント処理
  const onCount = (e) => {
    if(e.target.className === 'countUp'){
      props.handleCount(props.count + 1);
    }else if(e.target.className === 'countDown'){
      props.handleCount(props.count - 1);
    }
  };

  return (
    <div className='buttonArea'>
      <button className='countUp' onClick={onCount}>
        +1
      </button>
      <button className='countDown' onClick={onCount}>
        -1
      </button>
    </div>
  );
}

export default App;
```

雑なコードですが、とりあえずできたものをchatGPTに見てもらいました。

![スクリーンショット 2024-11-24 180433.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/78e1d9ee-18f9-6dfc-b578-4a646868588d.png)

そして、3つの改善点を出してくれました。

・改善点1
![スクリーンショット 2024-11-24 180444.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/8a48669c-60b7-136a-d044-b61cb10d031d.png)
これはいい改善点だと自分も思いました。
わざわざCountButtonコンポーネントに、countを渡す必要はなかったですね。

・改善点2
![スクリーンショット 2024-11-24 180459.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/118f3090-a8f7-aa3f-0a16-696780c4e45f.png)
確かにその通り、というより、今考えたらなぜわざわざクラスで分けたのか？
その場の思いつきで適当にやるのは良くないですね。


・改善点3
![スクリーンショット 2024-11-24 180510.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/dd7adb9f-29f9-c806-bcbb-f8a48a4b8cee.png)
なるほど、propsの中身が一つなら、この方が分かりやすいかもしれないですね。
全部propsで統一するのもありな気はしますが。

そして、改善後のコードも貼ってくれました。
```App.js
import './App.css';
import { useState } from 'react';

function App() {
  const [count, setCount] = useState(0);

  const handleCount = (delta) => {
    setCount((prevCount) => prevCount + delta);
  };

  return (
    <div className='App'>
      <View count={count} />
      <CountButton handleCount={handleCount} />
    </div>
  );
}

function View({ count }) {
  return <div className='view'>{count}</div>;
}

function CountButton({ handleCount }) {
  return (
    <div className='buttonArea'>
      <button onClick={() => handleCount(1)}>+1</button>
      <button onClick={() => handleCount(-1)}>-1</button>
    </div>
  );
}

export default App;
```

後は改善理由も。
![スクリーンショット 2024-11-24 180528.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/90c9bad5-77bd-7d9a-d9af-36ea22fd5702.png)

こういった勉強は、自分一人の勉強だと、どこがダメだったとか分からなかったりするので、良くなかったところをはっきりできるのは良いですね。

# 課題2

という訳で、さらに次の課題も出してもらいました。
![スクリーンショット 2024-11-24 180545.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/bd84d2cb-a4c6-74a9-5f73-89e81c8a14fa.png)
![スクリーンショット 2024-11-24 180557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/6c83d3e4-7cc9-b82f-208e-741f4735c722.png)
![スクリーンショット 2024-11-24 180609.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/e1a8d60a-9954-441c-b0d1-d7dd891c1ace.png)
![スクリーンショット 2024-11-24 180619.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/beae27dc-bd3f-d67c-fcb4-6d8e515786ec.png)

↓ 今回は、実装例のイメージまで、出してくれていています。
![スクリーンショット 2024-11-24 180731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/95e30e39-7471-3bce-d2af-6440b910199b.png)
![スクリーンショット 2024-11-24 180741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/6e51009e-fba5-73c2-1b98-192683bdf53e.png)

<br>

という訳で、早速作りはじめ、できたのがこちら。
・動作画面
![動作.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/93c7444b-951f-2fa0-0174-6338d61f6153.gif)
・コード
```App.js
import './App.css';
import { useRef, useState } from 'react';

function App() {
  const [tasks, setTasks] = useState([]);

  // タスクを追加する関数
  const addTask = (task) => {
    setTasks([...tasks, { id: Date.now(), text: task }]);
  };

  // タスクを削除する関数
  const deleteTask = (id) => {
    setTasks(tasks.filter(task => task.id !== id));
  };

  return (
    <div>
      <TaskInput addTask={addTask} />
      <TaskList tasks={tasks} deleteTask={deleteTask} />
    </div>
  );
}

function TaskInput(props) {
  const input = useRef(null);

  // 追加ボタン押下時
  const onAdd = (taskName) => {
    props.addTask(taskName);
    input.current.value = '';
  }

  return (
    <>
      <input ref={ input } type='text' />
      <button onClick={ () => onAdd(input.current.value) }>
        追加
      </button>
    </>
  );
}

function TaskList(props) {
  const rows = props.tasks.map(task => {
    return (
      <tr>
        <TaskItem task={task} deleteTask={ props.deleteTask } />
      </tr>
    );
  });
  return (
    <table border='1'>
      <tr>
        <th>
          ID
        </th>
        <th>
          タスク名
        </th>
        <th>
          削除ボタン
        </th>
      </tr>
      { rows }
    </table>
  );
}

function TaskItem(props) {
  // 削除ボタン押下時
  const onDeleteTask = (id) => {
    props.deleteTask(id);
  }

  return (
    <>
    <td>
      { props.task.id }
    </td>
    <td>
      { props.task.text }
    </td>
    <td>
      <button onClick={ () => onDeleteTask(props.task.id) }>
        削除
      </button>
    </td>
    </>
  );
}

export default App;
```

以下返答。今回は改善点を5つ挙げてくれました。

・改善点1
![スクリーンショット 2024-11-30 203403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/6d8acc29-1ede-6f67-1a0c-a7277122a72e.png)

・改善点2
![スクリーンショット 2024-11-30 203431.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/c8d08f4a-7060-1e6d-9389-b68d083257f8.png)

・改善点3
![スクリーンショット 2024-11-30 203440.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/1d6acc0f-4b7c-c5b2-ecf1-2ce150b8b750.png)

・改善点4
![スクリーンショット 2024-11-30 203452.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/7a06099c-b7d1-c32d-fed2-27db476c9172.png)

・改善点5
![スクリーンショット 2024-11-30 203457.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/f181d427-7170-954c-507c-df9c41f0c97d.png)

（※ 改善後のコードは割愛）

![スクリーンショット 2024-11-30 203515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831969/ed4b09da-8e92-7888-bcaa-d6d2647429de.png)


全体的に、かなり的確な指摘だと思いました。

keyのことは知っていましたが、ちゃんと使ったことがなかったので、忘れていました...
keyについてだけでなく、ここで指摘された内容に関しては、今度から気を付けるようにしないといけないですね。


# おわりに

今回、試しにやってみましたが、個人的には自分一人で勉強するよりも、かなりやりやすく感じました。
途中で分からなければヒントを聞けますし、できた後は、改善点を挙げてくれたりするのも良かったです。
今後も、Reactの勉強、または、別の言語を勉強する際などには、積極的に使っていこうと思いました。

以上です。ありがとうございました。