25
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

react-rails で Rails の Controller 側のデータを React Component でレンダリングするサンプル

Posted at

Rails のサーバーサイドでやりくりしているデータを React でレンダリングする方法を調べたメモです。

こちらの記事の続きです。
react-rails と webpacker を使って Rails アプリケーション上で React を動かす

前提

検証環境

実現までのざっくりした流れ

大きく分けて以下2ステップで作成します。

  1. Rails の Contoller のデータを JSON 返却する API を作成
  2. 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 で返却したいサンプルデータをハッシュで定義します。

app/controllers/api/v1/welcomes_controller.rb
class Api::V1::WelcomesController < ApplicationController
  def index
    @data = { greeting: "HelloFromAPI" }
  end
end

view 作成

jbuilder を使い、 JSON を返却する view を定義します。

app/api/v1/welcomes/index.json.jbuilder
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 で指定します。

app/views/welcomes/index.html.erb
<%= react_component("HelloWorld", url: "/api/v1/welcomes") %>

React の Component 編集

React の公式ドキュメントを参考に、React の Component を下記のように修正します。ざっくり下記のような処理を追加しています。

  • constructor で state を定義する
  • componentDidMount() 内で、this.props.url で指定したAPIを ajax で呼び出し、結果を state にセット
  • render() 内で state の内容を表示
app/javascript/components/HelloWorld.js
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-serverrails s を実行した状態で、 http://localhost:3000 にアクセスし、下記のような画面が表示されればOKです。

image.png

終わりに

今回は Rails の Contorller 側の データを ajax を使って React の Component で扱うやり方をさらいました。関連して Rails の API っぽい使い方や jbuilder にも触れてよかったです。

参考URL

25
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?