Edited at

React入門 -なぜReactを使うのか-


はじめに

私がReactに出会い1年程度経過し、React自体にも大きな変化がありました。今回は、Reactの良さを知ってもらいたいと思い、筆を取りました。

また、改めて自分の中のReactの知識を整理しようというのがサブ目標です。何回かに分けて1つのアプリを作れる程度までを記事にまとめていきたいと思ってます。

筆者のステータスは以下の通りです


  • React・Next.jsを使って簡単なアプリを作ったことがある

  • アルバイトでSpringを使ったwebアプリの開発をしている(フロントはjQueryゴリゴリ)


Reactに出会って使用するに至った経緯

概略: jQueryで地獄を見たためReactに救いを求めました。

前述の通りjQueryを良く使用していて基本は問題なかったのですが、画面項目が増え動きがリッチになるにつれ実装難易度やメンテナンス性に限界を感じてきました。

そこでたまたま出会ったのがReactでした。しかし、調べてみても「MVCのVのみを担当するフレームワークで ──」「仮想DOMが──」などと説明されていても「は?」って感じで、イマイチどういったモノなのか掴めずにいました。

しかし実際に使ってみると、実にシンプルなフレームワーク/ライブラリであり、悩みを解決してくれる存在であることがわかりました。元々JSが好きだったのもありとても馴染みやすかったです。


Reactとは

公式ドキュメントには以下のように紹介されてます。


A JavaScript library for building user interfaces

ユーザインターフェース構築のための JavaScript ライブラリ


これだけではわからないので、主な機能の説明と実装例を用いて紹介していきたいを思います。


Reactを使うと何がいいのか?

こちらも公式ドキュメントのトップから抜粋


  1. Declarative (宣言的なView)

  2. Component-Based (コンポーネントベース)

もう1つ「Learn Once, Write Anywhere (一度学習すれば、どこでも使える)」ということが挙げられていますが、これは一旦スルーで。


Declarative (宣言的なView)

まず「宣言的」って何?というとこですね。

Reactで実装する際に私たちが実装するのは「ある状態において何が表示されるべきか」です。

「この値をここに表示して」「この場合はこっちを表示して」というのをただただ宣言していけば良いわけです。

そしてその宣言通りに効率良くUIの更新(DOMの操作)をする必要があります。

そこで登場するのが仮想DOMです。仮想DOMは通常のDOMと同じツリー構造をとります。

仮想DOMが構築し直されると、差分のみが実際のDOMに反映される、といった具合です。

v-dom.png

仮想DOMの構築はサーバーサイドレンダリング(SSR)でテンプレートエンジンを使ってHTMLを生成するのに良く似ています。SSRでの描画で画面の値が不整合になったなんていう記憶はないので、それに近い方法を取れる仮想DOMを使わない手はありません。

加えて、必要な箇所のDOMの更新しか行われないため、下手なピュアのJSよりもパフォーマンスが向上します。


Component-Based (コンポーネントベース)

ReactではUIの状態、見た目、動きをコンポーネントという単位で分割します。単純な入力欄からページまで全てをコンポーネントとみなします。コンポーネントを組みわせていくことでUIを構築していきます。

分割することで再利用が可能になり、全体的な見た目の統一感を生みます。

コンポーネントは自身の状態を管理し、見た目と振る舞いを定義します。そのため状態をDOMに置くことがなくなります。DOMにある値はどこからでも変更可能ですが、コンポーネントの状態はアクセスできるスコープが限られるので状態の遷移が追いやすくなります


Reactを書いてみる


九九を表示するアプリを考える


  1. 何の段を表示させるかを入力する

  2. 入力された段の九九の表を表示する


jQueryの場合

Reactで書く前に比較対象としてjQueryを使った場合の実装をのせておきます


See the Pen
kuku_jQuery
by nabekou (@nabekou29)
on CodePen.

data属性にかける値を持たせておいて、値が入力された際に、data属性のあるtdタグのテキストを書き換えていく感じです。


Reactの場合

こちらがReactでの実装です。説明しやすさも考えてTypeScriptで書いてます。


See the Pen
kuku_React
by nabekou (@nabekou29)
on CodePen.


解説


コンポーネントの定義.tsx

const App: React.FunctionComponent<{defaultValue: number}> = ({defaultValue}) => {...}


この関数がコンポーネントです。(Classで定義する方法もあります。)

属性を引数に受け取ることができます。


状態を扱う.tsx

const [num1, setNum1] = React.useState(defaultValue);


React.useStateを使うことでこのコンポーネントで状態を持つことができます。

num1が状態、setNum1num1を更新するための関数です。setNum1を通して値を更新することでReactに値が変わったことを知らせています。


JSX.tsx

return (

<div>
<input type="number" value={num1} onChange={handleNum1Change} />の段
<table>
<tbody>
<tr><th>1</th><td>{1 * num1}</td></tr>
{/* 省略... */}
</tbody>
</table>
</div>
);

関数のコンポーネントでは、React要素returnします。React要素はJSXにより作成可能です。コンパイルすることでReact要素を作成する関数に変換されます。(変換後はCodePenの「View Compiled」ボタンから確認できます)。

このHTMLっぽい書き方がJSXです。あくまでそれっぽいだけなので、本来存在しない属性や一部名前が変わっている属性が存在します。JSXのなかで{}で囲まれた中にJSを書くことが可能です。当然そのJS内でもJSXを書けます。


データバインディング.tsx

const handleNum1Change = (event: React.ChangeEvent<HTMLInputElement>) => { 

setNum1(Number(event.target.value));
}

値を入力した時にnum1を更新します。setNum1を使って更新することで表の値が更新されます。

ReactDOM.render(

<App defaultValue={1}/>,
document.getElementById('app')
);

React要素を#appに描画しています。


ちなみに


before.tsx

<table>

<tbody>
<tr><th>1</th><td>{1 * num1}</td></tr>
<tr><th>2</th><td>{2 * num1}</td></tr>
<tr><th>3</th><td>{3 * num1}</td></tr>
...
<tr><th>9</th><td>{9 * num1}</td></tr>
</tbody>
</table>

HTMLに寄せて書きましたが、Arrayを用いて以下のように書くことが出来ます。


after.tsx

<table>

<tbody>
{
[1, 2, 3, 4, 5, 6, 7, 8, 9].map(num2 => (
<tr key={num2}><th>{num2}</th><td>{num1 * num2}</td></tr>
))
}
</tbody>
</table>


比べてみる


  1. Declarative (宣言的なView)

  2. Component-Based (コンポーネントベース)

上の2つを意識して比べてみようと思います


宣言的なView 的には?

特に<td>{num1 * num2}</td>のところがとてもわかりやすくなっていると思います。表に何が表示されるかがより明らかになりました。

また、更新がとても楽になっています。jQueryでは各td要素にアクセスして計算・更新をしていましたが、Reactではnum1を更新するだけで表の値が更新されています。


コンポーネントベース 的には?

見た目と動きが一体となったことで、状態の変化がどのように行われて、どういった作用をもたらすのかがぱっと見で分かるようになりました。JSとHTMLを行ったりきたりする必要が無くなりました。

さらに、変にセレクタを書いたりする必要性が無くなりました。どうせ密な結合になるならこっちの方がわかりやすいと思います。


おわりに

Reactは学習コストが重いと良く言われている気がしますが、覚えることは圧倒的に少ないです。ただJSに対する知識がそれなりに求められるので、そこが難しいところなのかなと思います。Hooksの登場で書きやすさもかなり向上したので、これからも周りに布教していきたいと思います。

次はもう少し実装よりの話をする予定です。


参考

React公式

Reactを使うとなぜjQueryが要らなくなるのか

ReactとVueのどちらを選ぶか

フロントエンドのコンポーネント設計に立ち向かう