Rails&Reactでいいね機能を実装する方法【react_on_rails編】

この記事はこんな方向けに書いています。

  • RailsにReactを導入したい方
  • jQueryのコーディングに限界を感じている方
  • 話題のライブラリに触れたい方
  • 非同期処理を実装したい方
ケイ
ケイ

こんにちは!
ケイ(@new_design)です。

今回はRailsとReactを使って『いいね機能』を実装する方法について解説していきます。Twitterなどで見かけるハートマークのやつですね。

いいね機能がついたアプリの例

React初心者はまずUdemyで学習しよう!

Reactを触ったことがない方がいきなりコードを書くのは無理だと思うので、まず基本の学習をするのをおすすめします。

そこでおすすめなのがUdemyの下記講座です。Javascriptの基礎から始まり、タスク管理アプリ作成を通してReactの基礎を学ぶことができます。

無料サンプル動画をチェック

またこの講座は2020年10月にリリースされた新しいものなので、最新のReactの技術を学ぶことができます。

ステップ0 Reactの環境構築編

なお今回もReactの環境構築が済んでいる前提で行いますので、まだの方はこちらの記事を先に読んでみてくださいね!(Webpackerなどバンドラーが必要になるので!)

【随時更新】Railsで作成したWebアプリにReactを導入する方法
Reactの環境構築編

ステップ1 Railsの準備編

今回解説で使用するアプリには『Board』『User』『Favorite』が存在することを前提にしています。
*Boardの部分は皆さんが作成したテーブル名でOKです。

ステップ1ー1 リレーションの準備編

class Board < ApplicationRecord
    belongs_to :user
    has_many :favorites, dependent: :destroy

    def favorite_by(user)
        favorites.find_by(user_id: user.id)
    end
end
class User < ApplicationRecord
  has_many :boards, dependent: :destroy
  has_many :favorites, dependent: :destroy
end
class Favorite < ApplicationRecord
	belongs_to :user
	belongs_to :board
end

ステップ1ー2 ルーティングの設定編

今回作成したアプリのルーティングは下記コードのようになっています。なおユーザーのログイン機能を『devise』で実装しています。

Rails.application.routes.draw do
  devise_for :users,
  root to: 'boards#index
  resources :favorites,only:[:create,:destroy]
  resources :boards
end

ステップ1−3 コントローラーの設定編

class BoardsController < ApplicationController
    before_action :authenticate_user!

    def index
        @boards = Board.all
    end

favorites_controller.rbではcreateとdestroyの2つのアクションを用意します。
どちらも『render json: favorite』とjsonで返していることがポイントです。

通常だとアクションの結果をView(HTML)で表示しますが、今回はいいねを非同期処理にしたいのでViewに返しません。

class FavoritesController < ApplicationController
	def create
		favorite = current_user.favorites.create!(favorite_params)
		render json: favorite
	end

	def destroy
		favorite = Favorite.find(params[:id])
		favorite.destroy!
		render json: favorite
	end

	private
	
	def favorite_params
		params.require(:favorite).permit(:board_id)
	end
end

ステップ2 Favorite.jsxを作成

Reactの環境構築ができたら、必要なファイルを作成していきます。
まずはjavascript配下にあるbundlesフォルダに『Favorite.jsx』を作成します。

作成できたら次のコードを貼り付けます。これがReactで重要な『コンポーネント』という部品です。

import PropTypes from 'prop-types';
import React, { useState } from 'react';
import { HeartFill } from 'react-bootstrap-icons';
import axios from 'axios'

axios.defaults.headers['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

const Favorite = (props) => {
	const { boardId, favoriteId } = props;
	const [id, setId] = useState(favoriteId);
	const [count, setCount] = useState(0)

	const clicked = async () => {
		if (id == null) {
			const { data: { id = null } } = await axios.post('/favorites', { board_id: boardId })
			id && setId(id);
		} else {
			await axios.delete(`/favorites/${id}`)
			setId(null);
		}
	}

	return (
		<>
			<HeartFill
				color={id ? 'red' : '#616161'}
				size={25}
				onClick={clicked}
			/>
		</>
	);
};

Favorite.propTypes = {};

export default props => <Favorite {...props} />;

なおコード内にある『board』は皆さんが作成したテーブルの名称によって変わります。

例えばArticleテーブルを作成した場合は、board_idのところがarticle_idなどになります。

ステップ3 bundle.jsを作成

コンポーネントができたら、bundle.jsを作成していきます。
javascript配下にあるpacksフォルダに『bundle.js』を作成し、下記コードを貼り付けます。

import ReactOnRails from 'react-on-rails';

import Favorite from '../bundles/Favorite';

// This is how react_on_rails can see the HelloWorld in the browser.
ReactOnRails.register({
  Favorite,
});

ここでreact_on_railsやFavorite.jsxの読み込みをします。ここの記述を抜かすと正しく表示されないので注意です!!

ステップ4 コンポーネントをViewで読み込む

最後にFavorite.jsxコンポーネントをView側で読み込みます。

@boards.each do |board|
 .card_name
   =board.name
 .card_description
   =board.description
 .card_favorite
   #Reactコンポーネントの読み込み
   = react_component("Favorite", 
   props: { boardId: board.id, favoriteId: 
   board.favorite_by(current_user)&.id }, prerender: false)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です