RailsでReactを触ってみた

info
- 2016.2
- React v15
- Rails 5.0.1
- docker使っとる

## RailsとReactの環境構築

RailsでReactを触ってみる前に、まず、Railsの環境構築から。

https://github.com/RyosukeCla/railsDock

まずは、Gemfileの中にreact-railsを追加する。

```text:./Gemfile
# Use React
gem 'react-rails', '~> 1.0'
```

次に、[ここ](https://github.com/RyosukeCla/railsDock)の __Get Started__ 通りにやるとReact入りのRailsの環境が整うっぽい。

```bash
$ rails g react:install
```
で、Reactがインストールされるらしい。

## Reactを触る

```bash
$ rails g react:component Playground
```
とやると、`app/assets/javascripts/components/`に`playground.js.jsx`とかいうのができる。

中を見ると、

```js:app/assets/javascripts/components/playground.js.jsx
var Playground = React.createClass({
  render: function() {
    return (
      ...
    );
  }
});
```
みたいな感じになっているのだけれども、今(2017.2.4)の[ReactのTutorial](https://facebook.github.io/react/tutorial/tutorial.html)を見ると、どうも書き方が違う。

自動生成されるコードはModule Pattern[(ここ参考)](http://qiita.com/kenju/items/a8a1009f5872a8b12568)っぽいけどもなんかセクシーじゃない(とは言っても、自分みたいなjs初心者はよく使っていたんだけども)。自分はjsのこういうクラスがごちゃごちゃなところが嫌いでAnti-JSマンだった。しかし、JSXだとES6？とかの構文でコードをカキカキできるらしい。これはOOR(Object Oriented Progamming)な書き方ができて、なんか気持よくなれるらしい。

ということで、さっきの`playground.js.jsx`を[ReactのTutorial](https://facebook.github.io/react/tutorial/tutorial.html)ぽく書き換えてみる。

```js:app/assets/javascripts/components/playground.js.jsx
class Playground extends React.Component {
  render() {
    return (
      Hello, world!
    );
  }
}
```

さて、Reactを実行してみようか。

```bash
$ rails g controller Playground
```
```app/views/playground/index.html.erb
<%= react_component('Playground') %>
```
```config/routes.rb
Rails.application.routes.draw do
  get '/play', to: 'playground#index'
end
```

Go to [localhost:3000/play](http://localhost:3000/play)

動く！！　しかも、`React.createClass()`の`()`とか`;`がなくなって非常に爽快感のあるコードになった。

あとは、チュートリアルやってみると面白いよ。
1. [react-railsを使ってReactのTutorialをやってみる](http://qiita.com/joe-re/items/96f12dda4a62470d1d7c)
2. [ReactのTutorial](https://facebook.github.io/react/tutorial/tutorial.html)

## Reactの感想

今までjQueryとか使ってたけども、Reactという現代に乗っかるとJsがかっこよく見えてくるものだね。

あと、Railsもいいね。

## チュートリアルの補足
[1のチュートリアル](http://qiita.com/joe-re/items/96f12dda4a62470d1d7c)なんだけども、変更点を幾つか。

### 1. Ajax
Ajaxについてなのだけれども、このチュートリアルだとjQueryを使っているんだよね。ただ、jQueryを使ってAjaxをしなければいけないのかと言われれば、そうではなくて、せっかくなのでjQueryは使いたくない。

どうやら、Fetch APIとかいうのがあるらしく、こちらのほうでAjaxを書いてみようとのことだ。

#### Get 側

```js
    fetch(this.props.url).then(function(responce) {
      return responce.json();
    }).then(function(json) {
      this.setState({data: json.data});
    }.bind(this));
```

#### Post　側

```js
    fetch(this.props.url, {
      method: "POST",
      headers: {
        'content-type': 'application/json'
      },
      body: JSON.stringify(comment)
    }).then(function(responce) {
      return responce.json();
    }).then(function(json) {
      this.setState( {data: this.state.data.concat([json])} );
    }.bind(this));
```

### 2. Key
どうやら、Reactにはkeyという概念があるらしく、Keyを設定するとパフォーマンスが上がるらしい。というより、keyつけないと、ワーニングがでる。

```js
var commentNodes = this.props.data.map(function(comment, i) {
  return (
    <Comment author={comment.author} key={i}>
      {comment.text}
    </Comment>
  );
});
```

### 3. DOMのfind
`React.findDOMNode(??)`だとエラーが起きるので、`ReactDOM.findDOMNode(??)`を使う。

### 4. CommentのPost
チュートリアルで遊んでるとCommentにNullをインサートしてしまう恐れがあり、エラーが起きまくるので修正しとこう（自分はここで少し詰まってしまった）。

```app/models/comment.rb
class Comment < ApplicationRecord
  validates :author, presence: true
  validates :text, presence: true
end
```