出来る限り短く説明するReactJS入門

**VTeacher 所属の Masaki Suzuki です。**
**※各項目をできるだけ3行以内にまとめています**

デザイナーさんやフロントのエンジニアさん向けのReact.js（リアクトジェーエス）入門です。
「最近、『リアクト』と聞くけど、つまり何？」ってひとが対象です。

# React.jsとは
React.jsはUIのパーツ（構成部品）を作るためのライブラリです。
FacebookがOSSとして公開しています。

### 初回投稿日：2015年06月21日

この投稿はReactが話題になり始めた頃（6年前のv0.1の頃）、整理した記事です。

#### 最新情報はこちら

- React Server Components
  - 2021年からReactを始めるなら React Server Components 一択ではないか？  
https://zenn.dev/rgbkids/articles/e58ef9b947b199

- React 18
https://ja.reactjs.org/blog/2021/06/08/the-plan-for-react-18.html  
  - 自動で有効になるパフォーマンス改善（例：自動バッチング）
  - 新たな API（例：startTransition）
  - React.lazy の組み込みサポートを有する新しいストリーミングサーバレンダラ


## React.jsはどのようなケースに使うのか？
例えば、下記のように、idに'dentaku'を指定すると
「電卓フォームが表示され、ボタンを押すと、ちゃんと計算もできる」
というような部品を作るときに向いています。

```html:sample.html
<html>
  <body>
    <div id='dentaku'></div>
    ...
  </body>
</html>
```

# すでに世界中のデベロッパーがReact.jsによるUIパーツ作りに取り組んでいます
**Date Pickerの例**
ElementalUIのサイトをご覧ください。
http://elemental-ui.com/

# デザイナーさん、エンジニアさん向けアドバイス
React.jsの良さが活きるのは、ボタン（`<input type='button'>`...）やテキスト（`<input type='text'>`...）などがいっぱいあって、入力した値を即座に表示するような画面です。
デスクトップアプリのUI/UX設計のイメージです。
コーダーさんならReact.jsの書き方に見慣れておく必要があると思います（少々独特のため）。
React.jsは、jQueryのようにアニメーションが得意なわけではなく、見せ方・表現などの利用には向いていません。
（アニメーションはReact次期開発の課題として挙げられているとのことです）

## 実際にReact.jsが動いているものを見たい
React.jsはFacebookが作っていますので、Facebookの画面（UI）が参考になると思います。
最近注目のエディターGitHubのATOM（ https://atom.io/ ）もそうです。
上で紹介した ElementalUI ( http://elemental-ui.com/ ) も参考になると思います。

# どこの企業が導入してるの？
開発を行っているFacebookやInstagramはもちろん、YahooやAirbnb、
GitHubのATOM（ https://atom.io/ ）など。

# React.jsはライブラリ？フレームワーク？
React.jsはM-V-C（M-V-MV）で言うところのViewの一部の機能を提供するライブラリ（コンポーネント＝UIの部品）です。
ですので、比較対象として挙げられるBackbone.jsやAngular.jsとも併用できます。

# React.jsを導入するメリットは？
- パフォーマンスが良い（仮想DOMが高速）！
【参考】リアルなDOMは遅い、仮想DOM（React.js）は速い
http://steps.dodgson.org/b/2014/12/11/why-is-real-dom-slow/

- 規模が大きくなっても管理しやすい！
jQueryやBackbone.js、Angular.jsは規模が大きくなったときに管理するのが難しい。 
逆に、React.jsは小さいアプリケーションを高速に開発するためのライブラリではないと言われています。

# どの環境でも導入できるの？
ブラウザがhtml5に対応していることが条件。いわゆるモダンブラウザなら動きます。
IE8以下など、古いブラウザはhtml5shiv.jsなどを導入し、html5相応の機能を持たせて対応（Polyfills）。
公式サイトに対応ブラウザのことが書かれています。
http://facebook.github.io/react/docs/working-with-the-browser.html

# 実際に書いてみたい
facebookのReact.jsファイルを読み込む（6/21時点の最新バージョンは0.13.3）

```html:sample.html
<script src="http://fb.me/react-0.13.3.js"></script>
<script src="http://fb.me/JSXTransformer-0.13.3.js"></script>
```

これで最低限の準備完了です。

## fb.me（Facebook）のjsを直接指定しないといけないの？
公式サイトからスターターキットをダウンロードしてReact.jsファイルを入手する方法もあります。
https://facebook.github.io/react/

# JSXについて
React.jsは通常JSX（Facebookが開発した独自タグの技術）を使用するため、プリコンパイルが必要ですが、開発者は意識する必要はありません。JSXTransfomerが自動でやってくれます。
しかし、それなりのアプリケーションになりますと、自動コンパイルの時間がかかるので、あらかじめ手動でのビルドが推奨されます。

## react-toolsによるJSXのビルド（任意）
Node.js,npmをインストールし
`$npm install -g react-tools`
srcのjsxファイルを変換しdestに保存
`$jsx -x jsx --watch src/ dest/`

# 一番簡単なサンプルコード

```html:sample.html
<!DOCTYPE html>
<html>
  <head>
    <script src="http://fb.me/react-0.13.3.js"></script>
    <script src="http://fb.me/JSXTransformer-0.13.3.js"></script>
  </head>
  <body>
    <div id="app"></div><!-- ←ここに埋め込まれる -->
    
    <!-- 以下、Reactのプログラム -->
    <!-- (jsxを使っているのでtext/jsxと書く) -->
    <script type="text/jsx">
     var HelloWorld = React.createClass({
       // <HelloWorld />をレンダリング（表示）
       render: function() {
         return (
           <p>Hello!World!</p>
         );
       }
     });
     
     // id='app'に<HelloWorld />を埋め込む（マウント）
     var m = React.render(<HelloWorld />, document.getElementById('app'));
    </script>
  </body>
</html>
```

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="wvdjWEE" data-editable="true" data-user="rgbkids-the-decoder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/rgbkids-the-decoder/pen/wvdjWEE">
  react-sample1</a> by rgb(suzuki) (<a href="https://codepen.io/rgbkids-the-decoder">@rgbkids-the-decoder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# 入力フォームを使ったサンプルコード（Web+DB vol.86改）

```html:sample2.html
<!DOCTYPE html>
<html>
  <head>
    <script src="http://fb.me/react-0.13.3.js"></script>
    <script src="http://fb.me/JSXTransformer-0.13.3.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="text/jsx">

     // 親：<Parent />の定義
     var Parent = React.createClass({
       // State（※状態は親が管理）
       // この値はブラウザを閉じたり、リロードするまでは保持される
       getInitialState: function () {
         return {
           textVal: "",
           children: []
         };
       },

       // State(textVal)を変更
       setStateTextVal: function(textVal) {
         this.setState({ textVal: textVal }); 
       },

       // State(children)を変更
       setStateChildren: function(textVal) {
         var textVals = this.state.children.concat(textVal);
         this.setState({ children: textVals });
       },

       // <Parent />の表示
       // ここで子となる<ChildInput />と<Child />を記述
       render: function() {
         return (
           <div>
             <p>入力してEnterキーを押す</p>
             <ChildInput onChange={this.setStateTextVal} onSave={this.setStateChildren} />
             <Child textVal={this.state.textVal} children={this.state.children} />
           </div>
         );
       }
     });

     // 子1：<ChildInput />の定義（※props経由で親を参照できる）
     var ChildInput = React.createClass({
       _onChange: function (e) {
         this.props.onChange(e.target.value);
       },

       _onKeyDown: function (e) {
         if (e.keyCode === 13) { // Enterキー
           this.props.onSave(e.target.value);
           e.target.value = "";
         }
       },

       // <ChildInput />の表示
       render: function() {
         return <input type="text" onChange={this._onChange} onKeyDown={this._onKeyDown} />;
       }
     });

     // 子2：<Child />の定義（※props経由で親を参照できる）
     var Child = React.createClass({
       // <Child />の表示
       render: function() {
         var key = 0;
         var textVals = this.props.children.map(function (textVal) {
           // 時間が同じ。つまり、キーが押されるごとに、まとめて再描画されていることに注目
           //（サーバーサイドっぽいと言われる所以）
           var date = new Date().toString();
           return <li key={key++}>{key}.{textVal}({date})</li>;
         });
         
         return (
           <div>
             <p>{this.props.textVal}</p>
             <ul>{textVals}</ul>
           </div>
         );
       }
     });

     // id='app' に <Parent />を表示する（マウント）
     var m = React.render(<Parent />, document.getElementById('app'));
    </script>
  </body>
</html>
```

<p class="codepen" data-height="300" data-theme-id="light" data-default-tab="html,result" data-slug-hash="LYymZdb" data-editable="true" data-user="rgbkids-the-decoder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/rgbkids-the-decoder/pen/LYymZdb">
  react-sample2</a> by rgb(suzuki) (<a href="https://codepen.io/rgbkids-the-decoder">@rgbkids-the-decoder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## ブラウザから簡単にコードを試すこともできます。

- CodePen  
  - https://codepen.io/  
- jsfiddle  
  - without JSX（JSX無し）  
https://jsfiddle.net/vjeux/VkebS/  
  - with JSX（JSXを使う）  
https://jsfiddle.net/vjeux/kb3gN/  

# 注目を浴びる理由
* Facebook産
* フロントエンドの考え方を根本的に覆す
* Virtual DOM
* コンポーネント指向
* リアクティブプログラミング
* 関数型言語（プログラミング）

# リアクティブ（Reactive）プログラミング
Reactの名前の由来にもなっていると思われます。
リアクティブプログラミングとは、「反応する側」と「認識する側」を分けて考え、反応に対して自動的に対応するという考え方です。
React.jsの説明では、必ずツリー構造の図が出てきます。ある要素が変更されたら、一方向の流れで、関係する要素も変更されるというものを表しています。

# なぜ今、関数型言語（プログラミング）が注目されているのか
関数型言語の代表はLisp。JavaScriptやScalaは、関数型言語っぽく書ける言語と言ったほうが正しいかもしれません。
関数型っぽく書くと、ほぼ純粋な関数（式）の集合体になるため、疎結合となり、ステート（状態）の管理が簡単になります。サーバー側の処理の場合、並列処理（マルチスレッド）が書きやすくなるなどのメリットもあります。

# React.js の仲間たち
* Flux
* Jest
* Immutable.js

# どこのサイトが勉強になる？（随時更新）
* 公式サイトチュートリアル
https://facebook.github.io/react/docs/tutorial.html

* 公式サイトExample
https://github.com/facebook/react/wiki/Examples
* koba04さん:Qiita
http://qiita.com/koba04/items/4d13caf5ab4507974bf0 
* koba04さん:一人React.js Advent Calendar
http://qiita.com/advent-calendar/2014/reactjs 
* React.jsチュートリアル【日本語翻訳】  
http://mae.chab.in/archives/2529 
* React (.js Facebook)解説 関数型プログラミングに目覚めた！ IQ145の女子高生の先輩から受けた特訓５日間 サポート記事　静的HTML編
http://kenokabe-techwriting.blogspot.jp/2015/04/react-js-facebook-iq145-html.html
* 今話題のReact.jsはどのようなWebアプリケーションに適しているか？ Introduction To React─ Frontrend Conference
https://html5experts.jp/hokaccha/13301/
* TodoMVC
http://todomvc.com/
* リアルな DOM はなぜ遅いのか
http://steps.dodgson.org/b/2014/12/11/why-is-real-dom-slow/
* ES6時代のJavaScript
http://techlife.cookpad.com/entry/2015/02/02/094607
* ElementalUI
http://elemental-ui.com/
* 伊藤直也氏が語る、モダンなWebテクノロジーに共通する傾向とは？ Chef、Docker、MicroservicesからReact、FRPまで。QCon TOkyo 2015
http://www.publickey1.jp/blog/15/qcon_tokyo_2015_1.html
http://www.publickey1.jp/blog/15/qcon_tokyo_2015_2.html
  
# 補足  
いとうなおやさんの言う「サーバーサイドっぽい」とは「アクションが起きたらとりあえず窓口へ行って、変更点以外もまとめてHTML更新」という点が似ているとのことだと思います。
※上記の【入力フォームを使ったサンプルコード】を実行すると表示時間が同じになります。つまり、キーが押されるごとに、追加された要素だけでなく、全要素まとめて再描画されていることに注目してください。


**※VTeacherでサブスクやっています**
VTeacherの「サブスク加入者のページ」から閲覧できます。
https://apps.apple.com/app/vteacher/id1435002381