Reactについて

# はじめに

いくつかフロントエンドフレームワークについてまとめて自分用のメモとして残すため記事にしました。  
初歩的なものになるので、初心者さん向けかと思います。

### React って？

React とは、Web 開発において UI 部分を構築する際に活用する Javascript ライブラリになります。  
React は利用率が最も高く（※The State of JS 2022 ）、学習コストもそこまで高くないのが特徴です。また、公式サイトで3つの特徴が挙げられています。

#### 宣言的な View

宣言的な View ってなんぞや？ってな感じですよね。  
頭の中でイメージできないと全く理解できない私には、以下の方の説明がとてもわかりやすかったです。  

https://zenn.dev/ken505/articles/ebc2e52a8687e7

#### コンポーネントベース

コンポーネントベースはなんとなく分かりますね。  
部分ごとにコンポーネントを分けることで、再利用しやすくて改修等も容易になります。

#### 一度学習すれば、どこでも使える

公式サイト（レガシー）より

> React と組み合わせて使用する技術に制限はありません。React を使って新しい機能を追加する際に、既存のソースコードを書き換える必要はありません。

素晴らしいですね。


# ではでは実際に使ってみる

今回はシンプルな TODO リストを作ってみました。
要件としては、

- テキストを入力して追加ボタンを押下したらリストに追加される
- テキストが入力されてなかったら追加ボタンを非活性にする
- TODO リストで実行済のものはチェックをつけることができる
- 実行済のタスクにはテキストに取り消し線を入れる

みたいな感じでシンプルなものです。

#### セットアップ

```bash
npx create-react-app --template typescript simple-todo-list
cd simple-task-app
```

#### コンポーネント作成


- App.tsx

```tsx
import React, { useState } from "react";
import "./App.css";
import TodoList from "./components/TodoList/TodoList";

export type Todo = {
  id: number;
  text: string;
  completed: boolean;
};

function App() {
  const [todoList, setTodoList] = useState<Todo[]>([]);
  const [addText, setAddText] = useState<string>("");

  /**
   * 入力欄ハンドラー
   */
  const handleInput = (e: React.ChangeEvent<HTMLInputElement>) => {
    setAddText(e.target.value);
  };

  /**
   * 追加ボタンハンドラ
   */
  const handleAddButton = () => {
    const newId =
      todoList.length < 1 ? 1 : todoList[todoList.length - 1].id + 1;
    setTodoList([
      ...todoList,
      {
        id: newId,
        text: addText,
        completed: false,
      },
    ]);
    setAddText("");
  };

  /**
   * チェックボックスハンドラ
   */
  const handleCheck = (id: number) => {
    setTodoList((prevTodoList) => {
      return prevTodoList.map((todo) => {
        if (todo.id !== id) {
          return todo;
        }
        const newTodo: Todo = { ...todo, completed: !todo.completed };
        return newTodo;
      });
    });
  };

  return (
    <div className="container">
      <header>
        <h1>TODO リスト</h1>
      </header>
      <main>
        <div>
          <input
            type="text"
            onChange={handleInput}
            className="text-input"
            value={addText}
          />
          <button
            type="button"
            onClick={handleAddButton}
            disabled={addText === ""}
          >
            追加
          </button>
        </div>
        <div>
          <TodoList todoList={todoList} onToggle={handleCheck} />
        </div>
      </main>
    </div>
  );
}

export default App;
```

- components/TodoList.tsx

```tsx
import React from "react";

import { Todo } from "../../App";
import TodoItem from "../TodoItem/TodoItem";

import "./index.css";

type Props = {
  todoList: Todo[];
  onToggle: (id: number) => void;
};

const TodoList = ({ todoList, onToggle }: Props) => {
  return (
    <div className="todo-list">
      {todoList.map((todo, index) => (
        <TodoItem todo={todo} onToggle={onToggle} />
      ))}
    </div>
  );
};

export default TodoList;
```

- components/TodoItem.tsx

```tsx
import React from "react";

import { Todo } from "../../App";
import "./index.css";

type Props = {
  todo: Todo;
  onToggle: (id: number) => void;
};

const TodoItem = ({ todo, onToggle }: Props) => {
  return (
    <div key={todo.id} className="todo-item">
      <input
        type="checkbox"
        checked={todo.completed}
        className="check-box"
        onChange={() => {
          onToggle(todo.id);
        }}
      />
      <span className={todo.completed ? "text text--done" : "text"}>
        {todo.text}
      </span>
    </div>
  );
};

export default TodoItem;
```

```bash
npm start
```

実行してみるとこんな感じです。
![画面収録 2024-03-17 12.19.20 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251276/a7571b04-3d89-fa06-15f4-f49be2aaafb1.gif)


コンポーネント内で変数を管理する場合は`useState`を使います。  
今回は簡単な TODO リストを作っただけなので使用していないですが、他にも Effect フック（`useEffect`）やパフォーマンス関連フック（`useMemo`）など、様々なフックがあります。  
また独自のカスタムフックを作成することも可能です。

https://ja.react.dev/reference/react/hooks

また、React は他のライブラリやツールを組み合わせて使用することができます。  
以前行ってた案件では、Material-UI や Formik、Axios、Redux を取り入れてました。


# まとめ

使用してみた感じ、Reactは個人的に直感的でわかりやすいなと感じています。  
（長らくプロジェクトで使っていたからだと思いますが…）
利用者数も多いため、何か開発で詰まった時に解決しやすいというのもメリットに挙げられるのかなと思います。

# 参考
https://ja.react.dev/learn

https://www.webstaff.jp/guide/trend/webit/react/

https://www.kagoya.jp/howto/it-glossary/develop/react/

https://wk-partners.co.jp/homepage/blog/hpseisaku/javascript/react-start/