To create a single-page application (SPA) in Laravel where all CRUD operations happen without page refresh, you can use React for the frontend and Laravel as the backend API. Below is a comprehensive guide to achieve this:


Step 1: Set Up Laravel Backend

  1. Install Laravel:
   composer create-project laravel/laravel laravel-react-spa
   cd laravel-react-spa
  1. Set Up Database:
  • Update your .env file with your database credentials:
    env 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
  1. Create a Model and Migration:
  • Generate a Post model and migration:
    bash php artisan make:model Post -m
  • Update the migration file (database/migrations/xxxx_xx_xx_create_posts_table.php):
    php public function up() { Schema::create('posts', function (Blueprint $table) { $table->id(); $table->string('title'); $table->text('content'); $table->timestamps(); }); }
  • Run the migration:
    bash php artisan migrate
  1. Create a Controller:
  • Generate a controller for API operations:
    bash php artisan make:controller Api/PostController --api
  • Update app/Http/Controllers/Api/PostController.php: 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); } }
  1. Define API Routes:
  • Update routes/api.php: use App\Http\Controllers\Api\PostController; Route::apiResource('posts', PostController::class);

Step 2: Set Up React Frontend

  1. Install React:
  • Use Laravel Mix to set up React:
    bash npm install react react-dom axios npm install
  1. Create React Components:
  • Create a folder resources/js/components and add the following files:
    • PostList.js (List all posts)
    • PostForm.js (Create/Edit a post)
    • PostItem.js (Show a single post)
  1. PostList.js:
   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;
  1. PostForm.js:
   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;
  1. PostItem.js:
   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;
  1. Update app.js:
  • In resources/js/app.js, render the PostList component: import React from 'react'; import ReactDOM from 'react-dom'; import PostList from './components/PostList'; ReactDOM.render( <PostList />, document.getElementById('root') );
  1. Update Blade View:
  • In resources/views/welcome.blade.php, include the React app:
    html <!DOCTYPE html> <html> <head> <title>Laravel React SPA</title> </head> <body> <div id="root"></div> <script src="{{ mix('js/app.js') }}"></script> </body> </html>
  1. Compile Assets:
   npm run dev

Step 3: Test Your Application

  • Run the Laravel development server:
  php artisan serve
  • Visit http://localhost:8000 to test your SPA.

Key Features

  • No Page Refresh: All CRUD operations are handled dynamically using React and Axios.
  • Reusable Components: PostForm is used for both creating and editing posts.
  • API Integration: Laravel serves as a backend API, and React fetches data using Axios.

Let me know if you need further assistance! 🚀

Related Post

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