Ensure Installed Dependencies

Presuming logic for the Item model and endpoint already exists along with CORS allowed, we should start by installing necessary dependencies.

npm install --save-dev webpack webpack-cli webpack-dev-server
npm install react react-dom redux axios
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader

Setup Webpack Configuration

Create a webpack.config.js file in the root directory so that we can start the server from the root directory by performing npm start.

const path = require('path');
module.exports = {
  entry: './frontend/index.js', // Entry file for React
  output: {
    // Name pattern for build files
    filename: 'bundle.js',
    // Output location
    path: path.resolve(__dirname, 'app/assets/javascripts'),
  },
  module: {
    rules: [
      {
        test: /\.js?$/, // Matches .js or .jsx files
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            // Transpile ES6+
            presets: ['@babel/preset-env', '@babel/preset-react'],
          },
        },
      },
    ],
  },
  resolve: {
    extensions: ['.js']
  },
  devtool: 'source-map',
  devServer: {
    contentBase: path.join(__dirname, 'public'),
    // Enable hot module replacement
    hot: true,
    // React app will run on port 8080
    port: 8080,
    // Proxy API requests to Rails server
    proxy: {
      '/api': 'http://localhost:3000',
    },
  },
};

Babel Configuration

Add .babelrc file at root directory.

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

Create React Components

Create react components in a directory named frontend.

// index.js

import React from 'react';
import ReactDOM from 'react-dom';
import ItemList from './ItemList;
ReactDOM.render(
    
  document.getElementById('root')
);
//ItemList.js

import React, { useState, useEffect } from 'react';
import axios from 'axios';

const ItemList = () => {
  const [items, setItems] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
    // Fetch the list of items upon component mount
    (async () => {
      try {
        const response = await axios.get('/api/items');
        setItems(res.data);
        setIsLoading(false);
      } catch (err) {
        console.error("Error fetching items:", err);
        setIsLoading(false);
      }
    })();
  }, []);

  if (isLoading) {
    return 
Loading...
; } return ( <>

Items

    { items.map( item => (
  • {item.name}
  • ) ) }
); }; export default ItemList;

Integrate React bundle in Rails View

In the Rails app, we will need to include the generated webpack bundle bundle.js in layout file app/views/layouts/application.html.erb before closing the tag.

<%= javascript_include_tag 'bundle.js' %>

Support On Demand!

Ruby on Rails

Related Q&A