React.jsを勉強した[MEMO]

# React.js勉強まとめ

久々にQiita投稿。

## React.jsとは
Facebook社が開発しているライブラリ。
コンポーネント思考のJavaScriptライブラリ。
必要なコンポーネントを作成して、必要なページごとに読み込む。

私が注目しているCMSであるDrupalでは標準サポートすることが決定したらしい。
DrupalはModuleとしても提供してますね。
https://www.drupal.org/project/react

## 勉強方法・参考サイト
### 公式のチュートリアル
[チュートリアル](https://reactjs.org/tutorial/tutorial.html)

### O'REILLYの本
[React ビギナーズガイド](https://www.oreilly.co.jp/books/9784873117881/)

## Let's Begin!!
### npm install
`npm install -g create-react-app`

```
npm install -g create-react-app

/usr/local/bin/create-react-app -> /usr/local/lib/node_modules/create-react-app/index.js
/usr/local/lib
└─┬ create-react-app@1.5.2 
  ├─┬ chalk@1.1.3 
  │ ├── ansi-styles@2.2.1 
  │ ├── escape-string-regexp@1.0.5 
  │ ├─┬ has-ansi@2.0.0 
  │ │ └── ansi-regex@2.1.1 
  │ ├── strip-ansi@3.0.1 
  │ └── supports-color@2.0.0 
  ├── commander@2.14.1 
  ├─┬ cross-spawn@4.0.2 
  │ ├─┬ lru-cache@4.1.1 
  │ │ ├── pseudomap@1.0.2 
  │ │ └── yallist@2.1.2 
  │ └─┬ which@1.3.0 
  │   └── isexe@2.0.0 
  ├─┬ envinfo@3.4.2 
  │ ├── minimist@1.2.0 
  │ └─┬ os-name@2.0.1 
release@1.1.0 
  │   └── win-release@1.1.1 
  ├─┬ fs-extra@1.0.0 
  │ ├── graceful-fs@4.1.11 
  │ ├── jsonfile@2.4.0 
  │ └── klaw@1.3.1 
  ├─┬ hyperquest@2.1.3 
  │ ├─┬ buffer-from@0.1.1 
  │ │ └─┬ is-array-buffer-x@1.7.0 
  │ │   ├── attempt-x@1.1.3 
  │ │   ├─┬ has-to-string-tag-x@1.4.1 
  │ │   │ └── has-symbol-support-x@1.4.2 
  │ │   ├─┬ is-object-like-x@1.7.1 
  │ │   │ ├─┬ is-function-x@3.3.0 
  │ │   │ │ ├── is-primitive@2.0.0 
  │ │   │ │ ├─┬ normalize-space-x@3.0.0 
  │ │   │ │ │ ├─┬ trim-x@3.0.0 
  │ │   │ │ │ │ ├── trim-left-x@3.0.0 
  │ │   │ │ │ │ └── trim-right-x@3.0.0 
  │ │   │ │ │ └── white-space-x@3.0.1 
  │ │   │ │ ├─┬ replace-comments-x@2.0.0 
  │ │   │ │ │ └── require-coercible-to-string-x@1.0.2 
  │ │   │ │ └── to-boolean-x@1.0.3 
  │ │   │ └── is-primitive@3.0.0 
  │ │   ├─┬ object-get-own-property-descriptor-x@3.2.0 
  │ │   │ ├─┬ has-own-property-x@3.2.0 
  │ │   │ │ └── cached-constructors-x@1.0.2 
  │ │   │ ├── is-falsey-x@1.0.3 
  │ │   │ ├─┬ is-index-x@1.1.0 
  │ │   │ │ ├── math-clamp-x@1.2.0 
  │ │   │ │ ├── max-safe-integer@1.0.1 
  │ │   │ │ ├─┬ to-integer-x@3.0.0 
  │ │   │ │ │ ├─┬ is-finite-x@3.0.4 
  │ │   │ │ │ │ └── infinity-x@1.0.2 
  │ │   │ │ │ ├── is-nan-x@1.0.3 
  │ │   │ │ │ └── math-sign-x@3.0.0 
  │ │   │ │ ├─┬ to-number-x@2.0.0 
  │ │   │ │ │ ├── nan-x@1.0.2 
  │ │   │ │ │ └── parse-int-x@2.0.0 
  │ │   │ │ └─┬ to-string-symbols-supported-x@1.0.2 
  │ │   │ │   └── is-symbol@1.0.1 
  │ │   │ ├── is-primitive@2.0.0 
  │ │   │ ├── is-string@1.0.4 
  │ │   │ ├── property-is-enumerable-x@1.1.0 
  │ │   │ ├─┬ to-object-x@1.5.0 
  │ │   │ │ └─┬ require-object-coercible-x@1.4.3 
  │ │   │ │   └── is-nil-x@1.4.2 
  │ │   │ └─┬ to-property-key-x@2.0.2 
  │ │   │   ├─┬ to-primitive-x@1.1.0 
  │ │   │   │ ├── is-date-object@1.0.1 
  │ │   │   │ └── is-primitive@2.0.0 
  │ │   │   └── to-string-x@1.4.5 
  │ │   └─┬ to-string-tag-x@1.4.3 
  │ │     ├── lodash.isnull@3.0.0 
  │ │     └── validate.io-undefined@1.0.3 
  │ ├─┬ duplexer2@0.0.2 
  │ │ └─┬ readable-stream@1.1.14 
  │ │   ├── isarray@0.0.1 
  │ │   └── string_decoder@0.10.31 
  │ └─┬ through2@0.6.5 
  │   ├── readable-stream@1.0.34 
  │   └── xtend@4.0.1 
  ├── semver@5.5.0 
  ├─┬ tar-pack@3.4.1 
  │ ├─┬ debug@2.6.9 
  │ │ └── ms@2.0.0 
  │ ├─┬ fstream@1.0.11 
  │ │ ├── inherits@2.0.3 
  │ │ └─┬ mkdirp@0.5.1 
  │ │   └── minimist@0.0.8 
  │ ├─┬ fstream-ignore@1.0.5 
  │ │ └─┬ minimatch@3.0.4 
  │ │   └─┬ brace-expansion@1.1.11 
  │ │     ├── balanced-match@1.0.0 
  │ │     └── concat-map@0.0.1 
  │ ├─┬ once@1.4.0 
  │ │ └── wrappy@1.0.2 
  │ ├─┬ readable-stream@2.3.5 
  │ │ ├── core-util-is@1.0.2 
  │ │ ├── isarray@1.0.0 
  │ │ ├── process-nextick-args@2.0.0 
  │ │ ├── safe-buffer@5.1.1 
  │ │ ├── string_decoder@1.0.3 
  │ │ └── util-deprecate@1.0.2 
  │ ├─┬ rimraf@2.6.2 
  │ │ └─┬ glob@7.1.2 
  │ │   ├── fs.realpath@1.0.0 
  │ │   ├── inflight@1.0.6 
  │ │   └── path-is-absolute@1.0.1 
  │ ├─┬ tar@2.2.1 
  │ │ └── block-stream@0.0.9 
  │ └── uid-number@0.0.6 
  ├─┬ tmp@0.0.31 
  │ └── os-tmpdir@1.0.2 
  └─┬ validate-npm-package-name@3.0.0 
    └── builtins@1.0.3 
```
色々入るなー

### module作成
`create-react-app my-app`

```
create-react-app my-app


Creating a new React app in /Users/hatoritakuya/work/javascript/react/sample/my-app.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts...


> fsevents@1.1.3 install /Users/[hogehoge]/react/sample/my-app/node_modules/fsevents
> node install

[fsevents] Success: "/Users/[hogehoge]/react/sample/my-app/node_modules/fsevents/lib/binding/Release/node-v48-darwin-x64/fse.node" already installed
Pass --update-binary to reinstall or --build-from-source to recompile

> uglifyjs-webpack-plugin@0.4.6 postinstall /Users/[hogehoge]/react/sample/my-app/node_modules/uglifyjs-webpack-plugin
> node lib/post_install.js

my-app@0.1.0 /Users/[hogehoge]/react/sample/my-app
├─┬ react@16.2.0 
│ ├─┬ fbjs@0.8.16 
│ │ ├── core-js@1.2.7 
│ │ ├─┬ isomorphic-fetch@2.2.1 
│ │ │ └─┬ node-fetch@1.7.3 
│ │ │   ├── encoding@0.1.12 

~~~~~~~~~~~~~~~~~~~~~~~~省略~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  │   └── yargs-parser@4.2.1 
  ├─┬ webpack-manifest-plugin@1.3.2 
  │ └─┬ fs-extra@0.30.0 
  │   ├── jsonfile@2.4.0 
  │   └── klaw@1.3.1 
  └── whatwg-fetch@2.0.3 

Success! Created my-app at /Users/[hogehoge]react/sample/my-app
Inside that directory, you can run several commands:

  npm start
    Starts the development server.

  npm run build
    Bundles the app into static files for production.

  npm test
    Starts the test runner.

  npm run eject
    Removes this tool and copies build dependencies, configuration files
    and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

  cd my-app
  npm start

Happy hacking!

```
FWやライブラリがコマンドだけで必要なモジュールを揃えてくれる。
良い時代に生まれてよかった。

### npm start
```
> npm start

> my-app@0.1.0 start /Users/[hogehoge]/react/sample/my-app
> react-scripts start

Compiled successfully!

You can now view my-app in the browser.

  Local:            http://localhost:3000/
  On Your Network:  http://192.168.11.4:3000/

Note that the development build is not optimized.
To create a production build, use npm run build.
```

<img width="509" alt="Screen Shot 2018-03-04 at 11.09.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/99413/cde813a5-104d-d940-7689-e0ffacfdd1e0.png">

わーい立ち上がったー

## Hello World

[React ビギナーズガイド](https://www.oreilly.co.jp/books/9784873117881/)のHello World。

本の内容は少し古い(2018年3月現在)。
Facebookでのバージョン管理しているリンクは存在しませんでした。
代わりにGitから本と同じバージョンを落としました。
https://github.com/facebook/react/releases/tag/v15.4.1

```html
<!DOCTYPE html>
<html>
   <head>
     <title>Hello React</title>
     <meta charset="utf-8">
   </head>
   <body>
     <div id="app">
     </div>
     <script src="react/react-15.4.1/build/react.js"></script>
     <script src="react/react-15.4.1/build/react-dom.js"></script>
     <script>
       ReactDOM.render(
         React.DOM.h1(null, "Hello world!"),
         document.getElementById("app")
       );
     </script>
   </body>
 </html>
```
### 実行結果
<img width="527" alt="Screen Shot 2018-03-04 at 17.47.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/99413/3cf9773b-d055-2cda-af17-5f3e45931063.png">


`meta`タグの閉じ忘れで2時間ハマったのは内緒。
この本一通りなめたら、バージョン上げてみよう。

## まとめ・感想
DrupalやらRailsなどサーバ側が強いCMS、FWを選定している場合は有効な選択肢だと思う。
理由は、ビュー側までリッチなFWを採用して勉強コストや複雑性をあげたくないから。
例えば、裏はRails、表はAngularにすると勉強コスト上がる。嫌。無理。[^1]

それなら、裏の処理とViewの表示までRailsに任せ切って、表はReact.jsとかで軽く実装してコンポーネント追加くらいでいいんじゃないかな。

また、同じようなパーツのコピペを防ぐことができるのは良いですね。
Angularで開発していると、画面は違うけれども同じ機能(一覧とか、モーダル開くとか)は沢山実装している。
その度にControllerとViewにコピペが量産されるので、それをコンポーネントとして一つのものにしておけるのはすごいメリットだなと感じました。

React.jsがAngularを邪魔するということもないはずなので採用してみたいな。

[^1]: 別に私個人が勉強をしたくないとかじゃなくて、新参者のハードルが高い。PGやSEなら勉強するのが当たり前という声は出そうだが、それはそれ。