Building a Single-Page Application (SPA) with Laravel and React

Creating a blog post about building a single-page application (SPA) using Laravel as the backend and React as the frontend is a great way to share your knowledge. Below is a blog post template that you can use to explain the process step-by-step.


Building a Single-Page Application (SPA) with Laravel and React

In this blog post, we’ll walk through the process of building a single-page application (SPA) using Laravel as the backend and React as the frontend. The application will perform CRUD operations (Create, Read, Update, Delete) on a Post model without requiring a page refresh.


Why Laravel + React?

  • Laravel: A powerful PHP framework for building robust backend APIs.
  • React: A popular JavaScript library for building dynamic and responsive user interfaces.
  • SPA: Single-page applications provide a seamless user experience by eliminating page reloads.

Step 1: Setting Up the Laravel Backend

1. Install Laravel

First, create a new Laravel project:

composer create-project laravel/laravel laravel-react-spa
cd laravel-react-spa

2. Set Up the Database

Update the .env file with your database credentials:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_database_user
DB_PASSWORD=your_database_password

3. Create a Model and Migration

Generate a Post model and migration:

php artisan make:model Post -m

Update the migration file (database/migrations/xxxx_xx_xx_create_posts_table.php):

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->string('title');
        $table->text('content');
        $table->timestamps();
    });
}

Run the migration:

php artisan migrate

4. Create an API Controller

Generate a controller for API operations:

php artisan make:controller Api/PostController

Update app/Http/Controllers/Api/PostController.php with CRUD methods:

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\Post;
use Illuminate\Http\Request;

class PostController extends Controller
{
    // List all posts
    public function index()
    {
        $posts = Post::all();
        return response()->json($posts);
    }

    // Store a new post
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required',
            'content' => 'required',
        ]);

        $post = Post::create($request->all());
        return response()->json($post, 201);
    }

    // Show a single post
    public function show($id)
    {
        $post = Post::findOrFail($id);
        return response()->json($post);
    }

    // Update a post
    public function update(Request $request, $id)
    {
        $request->validate([
            'title' => 'required',
            'content' => 'required',
        ]);

        $post = Post::findOrFail($id);
        $post->update($request->all());
        return response()->json($post);
    }

    // Delete a post
    public function destroy($id)
    {
        $post = Post::findOrFail($id);
        $post->delete();
        return response()->json(null, 204);
    }
}

5. Define API Routes

Update routes/api.php to define routes manually:

use App\Http\Controllers\Api\PostController;

// List all posts
Route::get('/posts', [PostController::class, 'index']);

// Store a new post
Route::post('/posts', [PostController::class, 'store']);

// Show a single post
Route::get('/posts/{id}', [PostController::class, 'show']);

// Update a post
Route::put('/posts/{id}', [PostController::class, 'update']);

// Delete a post
Route::delete('/posts/{id}', [PostController::class, 'destroy']);

Step 2: Setting Up the React Frontend

1. Install React and Axios

Install React and Axios for API communication:

npm install react react-dom axios
npm install @vitejs/plugin-react --save-dev
npm install

2. Create React Components

Create a folder resources/js/components and add the following files:

PostList.js

This component lists all posts and handles editing and deleting posts.

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import PostItem from './PostItem';
import PostForm from './PostForm';

const PostList = () => {
    const [posts, setPosts] = useState([]);
    const [editingPost, setEditingPost] = useState(null);

    // Fetch all posts
    useEffect(() => {
        fetchPosts();
    }, []);

    const fetchPosts = async () => {
        const response = await axios.get('/api/posts');
        setPosts(response.data);
    };

    // Delete a post
    const deletePost = async (id) => {
        await axios.delete(`/api/posts/${id}`);
        fetchPosts();
    };

    // Edit a post
    const editPost = (post) => {
        setEditingPost(post);
    };

    // Cancel editing
    const cancelEdit = () => {
        setEditingPost(null);
    };

    return (
        <div>
            <h1>Posts</h1>
            <PostForm
                post={editingPost}
                onSave={() => {
                    fetchPosts();
                    cancelEdit();
                }}
            />
            <ul>
                {posts.map((post) => (
                    <PostItem
                        key={post.id}
                        post={post}
                        onDelete={deletePost}
                        onEdit={editPost}
                    />
                ))}
            </ul>
        </div>
    );
};

export default PostList;

PostForm.js

This component handles creating and updating posts.

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

const PostForm = ({ post, onSave }) => {
    const [title, setTitle] = useState('');
    const [content, setContent] = useState('');

    // Pre-fill form if editing
    useEffect(() => {
        if (post) {
            setTitle(post.title);
            setContent(post.content);
        }
    }, [post]);

    // Handle form submission
    const handleSubmit = async (e) => {
        e.preventDefault();
        const data = { title, content };

        if (post) {
            await axios.put(`/api/posts/${post.id}`, data);
        } else {
            await axios.post('/api/posts', data);
        }

        onSave();
    };

    return (
        <form onSubmit={handleSubmit}>
            <input
                type="text"
                placeholder="Title"
                value={title}
                onChange={(e) => setTitle(e.target.value)}
                required
            />
            <textarea
                placeholder="Content"
                value={content}
                onChange={(e) => setContent(e.target.value)}
                required
            />
            <button type="submit">{post ? 'Update' : 'Create'}</button>
        </form>
    );
};

export default PostForm;

PostItem.js

This component displays a single post with edit and delete options.

import React from 'react';

const PostItem = ({ post, onDelete, onEdit }) => {
    return (
        <li>
            <h2>{post.title}</h2>
            <p>{post.content}</p>
            <button onClick={() => onEdit(post)}>Edit</button>
            <button onClick={() => onDelete(post.id)}>Delete</button>
        </li>
    );
};

export default PostItem;

3. Update app.js

Update resources/js/app.js to render the PostList component:

import React from 'react';
import ReactDOM from 'react-dom/client';
import PostList from './components/PostList';

// Get the root element
const rootElement = document.getElementById('root');

// Create a root and render your component
const root = ReactDOM.createRoot(rootElement);
root.render(<PostList />);

4. Update Blade View

Update resources/views/welcome.blade.php to load the React app:

<!DOCTYPE html>
<html>
<head>
    <title>Laravel React SPA</title>
</head>
<body>
    <div id="root"></div>

     @vite('resources/js/app.jsx') <!-- Include the compiled  --> 
</body>

5. Compile Assets

Compile the React components using Laravel Mix:

npm run dev

Step 3: Testing the Application

  1. Run the Laravel development server:
   php artisan serve
  1. Visit http://localhost:8000 to test the application.

Conclusion

In this blog post, we built a single-page application (SPA) using Laravel as the backend and React as the frontend. The application performs CRUD operations on a Post model without requiring a page refresh. This setup provides a seamless user experience and demonstrates the power of combining Laravel and React.

Feel free to extend this project by adding features like authentication, pagination, or deployment to a live server. Happy coding! 🚀


Let me know if you need further assistance or additional sections for your blog! 😊

  • Related Posts

    How Starlink Works: Revolutionizing Global Connectivity from Space

    How Starlink Works: Revolutionizing Global Connectivity from Space In today’s world, the internet has become an essential part of our lives, transforming the way we communicate, access information, and interact…

    Airtel and SpaceX Join Forces to Bring Starlink’s High-Speed Internet to India

    Airtel and SpaceX Join Forces to Bring Starlink’s High-Speed Internet to India In a groundbreaking move, Airtel and SpaceX have formed a strategic partnership to bring Starlink’s high-speed internet services…

    0 0 votes
    Article Rating
    Subscribe
    Notify of
    guest

    0 Comments
    Oldest
    Newest Most Voted
    Inline Feedbacks
    View all comments
    0
    Would love your thoughts, please comment.x
    ()
    x