なぜReactとかVueを使うの?

# ReactやVueを使う理由
## 初めに
さんざん使い古されたネタですが、大学の活動でJS初心者に教える機会があったので、その資料も兼ねて記事を作成しました。本記事ではReact.jsやVue.jsが何故利用されるのか、初心者でもわかるように解説していこうと思います(コードはReact)。

## バニラJSの場合
サンプルとして以下のようなコードを用意しました。

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p id="number"></p>
    <button onclick="increment()">increment</button>
    <script>
        let a=1
        console.log(a);
        document.getElementById("number").innerText=a
        const increment=()=>{
            a++
            console.log(a)
        }
    </script>
</body>
</html>
```
numberというidを持つpタグに、数字を埋め込むという簡単なプログラムです。pタグの数字を増やすために、ボタンと関数も定義してあります。一見問題なさそうに見えますが、これだと数字が更新されても、DOMが更新されないため表示が変わりません。以下の画像でもコンソールログには、数字が増えていく様子が確認できますが、ページの表示は1のままです。
![スクリーンショット 2021-06-17 021826.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591669/75cffb38-6547-e2e6-32c4-6e3e5b70397a.png)
DOMを更新させるには、increment関数に一行追加させる必要があります。

```js
const increment=()=>{
      a++
      console.log(a)
      document.getElementById("number").innerText=a //改めてDOMを書き換え
}
```
`document.getElementById("number").innerText=a`という記述が追加されました。これによりボタンが押され関数が起動する度に数字が大きくなり、その値を使ってDOMが更新されます。以下の画像でも数字がちゃんと反映されていることがわかります。
![スクリーンショット 2021-06-17 022639.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591669/7e456c46-c597-e44f-805e-e64e282f2863.png)
今回は更新する要素が一つしかないのでこれでも簡単です。しかし、複数の要素を更新させる場合は、以下のようになってしまい少し問題になります。

```html
<body>
    <!--数字埋め込み -->
    <p id="number"></p>
    <!-- 上の数字に+1 -->
    <p id="number1"></p>
    <!-- 更に+1 -->
    <p id="number2"></p>
    <button onclick="increment()">increment</button>
    <script>
        let a = 1
        console.log(a);
        //各要素に埋め込み
        document.getElementById("number").innerText = a
        document.getElementById("number1").innerText = a + 1
        document.getElementById("number2").innerText = a + 2
        const increment = () => {
            a++
            console.log(a)
            //3つだからまだいいけど･･･
            document.getElementById("number").innerText = a
            document.getElementById("number1").innerText = a + 1
            document.getElementById("number2").innerText = a + 2
        }
    </script>
</body>
```
DOMを更新させるために毎回同じような記述が増えて面倒ではないでしょうか?もしかすると、どこかでnumber1に変数aをそのまま代入してしまうかもしれません(+1を忘れてた･･･)。しかし、アプリケーションを作成していけば、必ず複数の変数(状態)を持ちますし、変数を更新する関数に毎回このような記述を増やしていくのは、ケアレスミスによるバグにもなりますし避けたいところです。できれば、変数を更新させたら同時かつ自動でDOMも更新して欲しいですよね。これを行ってくれるのがReactやVueといったフレームワークになります[^1]。

## React.jsの場合
実際にReactで書いたコードを見てみましょう。動作はCodeSandboxで確認しています。
[CodeSandbox](https://codesandbox.io/s/floral-monad-gi4v9)
### index.js
```jsx
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import { useState } from "react";

const App = () => {
  const [a, setA] = useState(1);
  return (
    <div>
      <p>{a}</p>
      <p>{a + 1}</p>
      <p>{a + 2}</p>
      <button onClick={() => setA(a + 1)}>increment</button>
    </div>
  );
};

ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  document.getElementById("root")
);
```
元のHTMLから大分見た目が変わりましたが、ここでは細かく解説はしません(また別に記事を作る予定です)。
CodeSandboxにアクセスしてもらえばわかるのですが、これで先程と同じ結果になるはずです。値の更新(setA関数)を一回行うだけで変数aを使用する要素が全て更新されます。これならいくらでも簡単に、変数aを使う要素を作れます。

```jsx
<p>{a}</p>
<p>{a + 1}</p>
<p>{a + 2}</p>
<p>{a + 3}</p>
<p>{a + 4}</p>
<p>{a + 5}</p>
     ︙
```
そしてReactやVueの強みはこれだけではありません。

## コンポーネント化
ReactやVueではコンポーネント化(複数の要素をまとめて一つの要素として扱えるようにすること)が非常にしやすいフレームワークです。実際にコンポーネントを作ってみましょう。
[CodeSandbox](https://codesandbox.io/s/aged-star-c8t6g?file=/src/index.js)

```jsx
import { StrictMode } from "react";
import ReactDOM from "react-dom";

const OriginalComponent = (props) => (
  <div>
    <p>{props.title}</p>
    <p>{props.description}</p>
  </div>
);

const App = () => {
  return (
    <div>
      <OriginalComponent title="React" description="簡単に画面が作れて便利" />
      <OriginalComponent
        title="CodeSandbox"
        description="環境構築いらずでお手軽"
      />
    </div>
  );
};

ReactDOM.render(
  <StrictMode>
    <App />
  </StrictMode>,
  document.getElementById("root")
);

```
上記のコードではOriginalComponentというコンポーネントを作成しました。これはdivタグの中に2つのpタグが含まれている要素です。Appもコンポーネントになっており、中では複数回OriginalComponentを利用しています。これによって、毎回divタグと2つのpタグを書かなくて良くなります。コンポーネント化を利用することで、同じ構造の要素であれば簡単に使い回せるんですね。

## 仮想DOM
ReactやVueで行われているDOM操作の手法で、更新時に変更部分を特定し、再レンダリングを最小限にする仕組みです。これにより無駄なレンダリングが減り、パフォーマンスが向上します。
筆者はこの仕組みについてそこまで詳しくないため、詳しくは[@Seria様の記事](https://qiita.com/seira/items/6767e222890c9890ecb9)などを参考するといいと思います。

## 最後に
これらがReactやVueの基本的な使い方であり、バニラJSやjQueryではやりにくいと言われる点になります。もちろんこの他に利点(TypeScriptとの相性など)は数多くありますし、様々な便利なライブラリ(Reduxや、React発展版のNext.jsなど)が提供されています。今バニラJSやjQueryを勉強することが無駄とは言えないでしょうが、実務で使われることはほとんどない[^2]そうですし、折角勉強するならこの先使うであろうReactやVue、あとはAngularあたりのフレームワークがいいんじゃないでしょうか。ReactやVueは、公式の日本語リファレンスが非常に充実しているので、勉強もしやすいと思います。フレームワークを活用してどんどんアプリを作っていきましょう!

[^1]: 一応バニラJSにもObject.observeというバインディングの仕組みはありますし、jQueryにも同様の機能はあると思います。しかし、それでアプリケーション作るならReact、Vueのほうが簡単な上、他にも利点があっていいのではないでしょうか?フレームワークが使えない環境なら･･･?
[^2]: 先日お話する機会のあったフロントエンドエンジニアの方々いわく、ここ2年はjQueryをプロダクト使ってないそうです。jQueryからReact、Vueに書き換えることが多いらしいですが･･･。しかし、デザイン業界ではまだまだ利用されることが多いらしいので、完全に死んでるわけではないのが厄介ですね･･･。