Rails のサーバーサイドでやりくりしているデータを React でレンダリングする方法を調べたメモです。
こちらの記事の続きです。
react-rails と webpacker を使って Rails アプリケーション上で React を動かす
前提
検証環境
-
Rails 5.1.6
-
ruby 2.4.3
-
Mac OS X 10.13.4
-
rails new したアプリケーションに下記 Gem がインストールされていること
-
react-rails と webpacker を使って Rails アプリケーション上で React を動かすの手順を追えていること
実現までのざっくりした流れ
大きく分けて以下2ステップで作成します。
- Rails の Contoller のデータを JSON 返却する API を作成
- API のレスポンスを React の Component で表示する
手順
1. Rails の Contoller のデータを JSON 返却する API を作成
API 用 Controller 作成
通常の Controller と namespace を分けて API 用の Controller を作成します。
--no-assets --no-helper
オプションで余計な assets や helper の生成を抑制しつつ作成します。
$ rails g controller api/v1/welcomes --no-assets --no-helper
Controller のアクションを定義
JSON で返却したいサンプルデータをハッシュで定義します。
class Api::V1::WelcomesController < ApplicationController
def index
@data = { greeting: "HelloFromAPI" }
end
end
view 作成
jbuilder を使い、 JSON を返却する view を定義します。
json.extract! @data, :greeting
routes 作成
API にアクセスするための route を追記します。
namespace :api, format: 'json' do
namespace :v1 do
resources :welcomes
end
end
JSONの返却確認
http://localhost:3000/api/v1/welcomes にアクセスし、下記のようなデータが表示されればOKです。
{"greeting":"HelloFromAPI"}
2. API のレスポンスを React の Component で表示する
表示したい React の Component 指定
JSON で返却できるようにしたデータを React の Component で表示します。
下記のように、表示したい Component と、JSON データを呼び出す API の URL を props で指定します。
<%= react_component("HelloWorld", url: "/api/v1/welcomes") %>
React の Component 編集
React の公式ドキュメントを参考に、React の Component を下記のように修正します。ざっくり下記のような処理を追加しています。
-
constructor
で state を定義する -
componentDidMount()
内で、this.props.url
で指定したAPIを ajax で呼び出し、結果を state にセット -
render()
内で state の内容を表示
import React from "react"
import PropTypes from "prop-types"
class HelloWorld extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
greeting: ''
};
}
componentDidMount() {
fetch(this.props.url)
.then(res => res.json())
.then(
(result) => {
this.setState({
greeting: result.greeting
});
},
// Note: it's important to handle errors here
// instead of a catch() block so that we don't swallow
// exceptions from actual bugs in components.
(error) => {
this.setState({
error
});
}
)
}
render () {
const { error, greeting } = this.state;
return (
<React.Fragment>
Greeting: {greeting}
</React.Fragment>
);
}
}
HelloWorld.propTypes = {
greeting: PropTypes.string
};
export default HelloWorld
なお、React で ajax を使うときは、componentDidMount
でコールし、setState
で Component を更新出来るようにすべきと書いてありました。React の公式ドキュメントの文章を以下に引用します。
Where in the component lifecycle should I make an AJAX call?
You should populate data with AJAX calls in the componentDidMount lifecycle method. This is so you can use setState to update your component when the data is retrieved.
画面表示確認
bin/webpack-dev-server
と rails s
を実行した状態で、 http://localhost:3000 にアクセスし、下記のような画面が表示されればOKです。
終わりに
今回は Rails の Contorller 側の データを ajax を使って React の Component で扱うやり方をさらいました。関連して Rails の API っぽい使い方や jbuilder にも触れてよかったです。