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
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', }, }, };
Add .babelrc file at root directory.
{ "presets": [ "@babel/preset-env", "@babel/preset-react" ] }
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
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' %>