Laravel Pagination with ReactJS using Vite

1 year ago admin Reactjs

In today's tutorial, we will see how to implement Laravel React js pagination using vite, as you know pagination is dividing content into several pages with links based on the current page.


Create the migration

I assume that you have already created a new Laravel application with React js already installed, if you do not know how to add Reactjs to Laravel 9 follow this tutorial.

Let's create the database with a tasks table, so the first thing we will do is create the migration.

                                                    
                                                                                                                
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body');
            $table->boolean('done')->default(0);
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('tasks');
    }
};


Create the controller

Next, let's create the TaskController with the method index which returns all the tasks paginated.

                                                        
                                                                                                                        
<?php

namespace App\Http\Controllers;

use App\Models\Task;
use Illuminate\Http\Request;

class TaskController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
        return Task::paginate(10);
    }
}



Create the route

Next, we will add the route in the file api.php.

                                                        
                                                                                                                        
Route::apiResource('tasks', TaskController::class);

Create the home component

In resources/js, we add new folder components inside the created folder we add a new file Home.jsx in which we implement the pagination with data retrieved from the API.

The structure of the folders:

  • resources
    • js
      • components
        • Home.jsx

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


export default function Home() {
    const [tasks, setTasks] = useState([]);
    const [page, setPage] = useState(1);

    useEffect(() => {
        fetchTasks();
    }, [page])


    const fetchTasks = async () => {
        try {
            const response = await axios.get(`/api/tasks?page=${page}`);
            setTasks(response.data);
        } catch (error) {
            console.log(error);
        }
    }

    const checkIfTaskIsDone = (done) => (
        done ? 
            (
                <span className='badge bg-success'>
                    Done
                </span>
            )
            :
            (
                <span className='badge bg-danger'>
                    Processing...
                </span>
            )
    )

    const fetchNextPrevTasks = (link) => {
        const url = new URL(link);
        setPage(url.searchParams.get('page'));
    }

    const renderPaginationLinks = () => {
        return <ul className="pagination">
            {
                tasks.links?.map((link,index) => (
                    <li key={index} className="page-item">
                        <a style={{cursor: 'pointer'}} className={`page-link ${link.active ? 'active' : ''}`} 
                            onClick={() => fetchNextPrevTasks(link.url)}>
                            {link.label.replace('&laquo;', '').replace('&raquo;', '')}
                        </a>
                    </li>
                ))
            }
        </ul>
    }

    return (
        <div className="my-5">
            <div className="card">
                <div className="card-body">
                    <table className="table">
                        <thead>
                            <tr>
                                <th>ID</th>
                                <th>Title</th>
                                <th>Body</th>
                                <th>Done</th>
                                <th>Created</th>
                            </tr>
                        </thead>
                        <tbody>
                            {
                                tasks.data?.map(task => (
                                    <tr key={task.id}>
                                        <td>{task.id}</td>
                                        <td>{task.title}</td>
                                        <td>{task.body}</td>
                                        <td>
                                            {
                                                checkIfTaskIsDone(task.done)
                                            }
                                        </td>
                                        <td>{task.created_at}</td>
                                    </tr>
                                ))
                            }
                        </tbody>
                    </table>
                    <div className="my-4 d-flex justify-content-between">
                        <div>
                            Showing {tasks.from} to {tasks.to} from {tasks.total} results.
                        </div>
                        <div>
                            {renderPaginationLinks()}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}



Update app.js & welcome page

Next, rename the file app.js to app.jsx, let's import the home component and add it to the app.

and do not forget to add the id app to your welcome page.

Laravel Pagination with ReactJS using Vite

                                                        
                                                                                                                        
//app.jsx 

import './bootstrap';

import ReactDOM from 'react-dom/client';        

import Home from './components/Home';

ReactDOM.createRoot(document.getElementById('app')).render(     
    <Home />        
);

//welcome page

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css" integrity="sha512-MV7K8+y+gLIBoVD59lQIYicR65iaqukzvf/nwasF0nqhPay5w/9lJmVM2hMDcnK1OnMGCdVK+iQrJ7lzPJQd1w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
        <title>Laravel React CRUD</title>
    </head>
    <body class="bg-light">
        <div class="container" id="app"></div>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
        @viteReactRefresh
        @vite(['resources/js/app.jsx'])
    </body>
</html>

Related Tuorials

Build a Shopping Cart Using React js Laravel 11 & Stripe Payment Gateway Part 5

In the last part of this tutorial, we will display the cart items, add the ability to increment/decr...


Build a Shopping Cart Using React js Laravel 11 & Stripe Payment Gateway Part 4

In the fourth part of this tutorial, we will fetch and display all the products on the home page, an...


Build a Shopping Cart Using React js Laravel 11 & Stripe Payment Gateway Part 3

In the third part of this tutorial, we will start coding the front end, first, we will install the p...


Build a Shopping Cart Using React js Laravel 11 & Stripe Payment Gateway Part 2

In the second part of this tutorial, we will create the product and payment controllers, and later w...


Build a Shopping Cart Using React js Laravel 11 & Stripe Payment Gateway Part 1

In this tutorial, we will create a shopping cart using React js Laravel 11 and Stripe payment gatewa...


How to Use Rich Text Editor in React js

In this lesson, we will see how to use rich text editor in React JS, let's assume that we have a com...


How to Download a File from the Server Using Laravel and React js

In this tutorial, we will see how to download a file from the server using Laravel and React js, let...


How to Add a Class on Hover in React js

In this lesson, we will see how to add a class on hover in React js, let's assume that we have a boo...


Drag and Drop Image and File Upload Using React and Laravel

In this tutorial, we will see how to upload files using drag and drop in React js and Laravel, first...


API Authentication Using Laravel Sanctum and React js Part 3

In the third part of this tutorial, we will register and log in the user, get the access token, and...