React + Data Grid + Spring Boot With Server-Side Pagination

React + Data Grid + Spring Boot With Server-Side Pagination

Overview

In this blog, we’ll learn how to connect a React frontend with a Spring Boot backend using Data Grid and implement pagination that works on the server-side. If you’ve already read my blog Implement Pagination using Spring Boot, then you’ve completed the backend part — now it’s time to show the paginated data in React using a smart and responsive data grid.

React + Data Grid + Spring Boot With Server-Side Pagination

What We’ll Build

If you’re working on a React + Spring Boot project and want to efficiently display large sets of data — pagination is a must!

In this article, we’ll learn how to implement server-side pagination using:

  • Spring Boot REST API with pagination support
  • React.js as frontend
  • MUI DataGrid for displaying data
  • Axios to call our backend APIs

We’ll walk through a real-world example where we fetch paginated product data from the backend and display it on the frontend using @mui/x-data-grid .

Our goal: When a user clicks on the next page in the data grid, the request goes to Spring Boot API with the page number and size, and the response comes back with that specific data — this is called server-side pagination.

What Is Server-Side Pagination?

In server-side pagination, the backend (Spring Boot) returns only the data for the current page requested by the frontend. The React frontend sends the page number and size, and gets back only that slice of data. This keeps the app fast and efficient, especially with large datasets

Step 1 : Create Spring Boot API for Pagination (already created)

Make sure your backend endpoint looks something like this as we have already created in the previous blog: Implement Pagination using Spring Boot


@GetMapping("/getProducts")
public Page<Product> getProducts(
    @RequestParam int page, 
    @RequestParam int size) {
    
    Pageable pageable = PageRequest.of(page, size);
    return productRepository.findAll(pageable);
}

This API returns a JSON like:


{
  "content": [
    {
      "id": 1,
      "name": "Laptop",
      "price": 50000
    },
    {
      "id": 2,
      "name": "Phone",
      "price": 20000
    }
    // ... more products
  ],
  "totalElements": 50,
  "totalPages": 5,
  "number": 0,
  "size": 10
}

Step-2 : Step-by-Step Implementation in Frontend

Install Required Packages

If you haven’t already set up a React app:


npx create-react-app react-pagination-demo
cd react-pagination-demo

Install Material UI and Axios:


npm install @mui/material @mui/x-data-grid axios

Frontend: React + MUI DataGrid Setup

Let’s use this React component to connect to the Spring Boot API:


import React, { useEffect, useState } from 'react';
import axios from 'axios';
import { DataGrid } from '@mui/x-data-grid';

const columns = [
  { field: 'id', headerName: 'ID', width: 250 },
  { field: 'name', headerName: 'Name', width: 400 },
  { field: 'price', headerName: 'Price', width: 300 },
];

const ProductTable = () => {
  const [products, setProducts] = useState([]);
  const [pageNumber, setPageNumber] = useState(0);
  const [pageSize, setPageSize] = useState(10);
  const [rowCount, setRowCount] = useState(0);
  const [loading, setLoading] = useState(false);

  const fetchProducts = async (page, size) => {
    setLoading(true);
    try {
      const response = await axios.get('http://localhost:8082/getProducts', {
        params: { page, size },
      });
      setProducts(response.data.content || []);
      setRowCount(response.data.totalElements || 0);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchProducts(pageNumber, pageSize);
  }, [pageNumber, pageSize]);

  return (
    <div style={ { margin: '30px' } }>
      <h2 style={ { margin: '0 0 10px 0', fontWeight: 700, color: '#222' } }>
        Product List
      </h2>

      <DataGrid
        rows={products}
        columns={columns}
        pagination
        paginationMode="server"
        rowCount={rowCount}
        pageSizeOptions={[10, 20, 50, 100]}
        loading={loading}
        paginationModel={{ page: pageNumber, pageSize: pageSize }}
        onPaginationModelChange={({ page, pageSize }) => {
          setPageNumber(page);
          setPageSize(pageSize);
        }}
      />

    </div>
  );
};

export default ProductTable;

How This Code Works

Let’s break it down step-by-step:

1. Columns Definition


const columns = [
  {
    field: 'id',
    headerName: 'ID',
    width: 250
  },
  {
    field: 'name',
    headerName: 'Name',
    width: 400
  },
  {
    field: 'price',
    headerName: 'Price',
    width: 300
  }
];

We define the columns to be shown in the grid: ID, Name, and Price

2. State Management


const [products, setProducts] = useState([]);
const [pageNumber, setPageNumber] = useState(0);
const [pageSize, setPageSize] = useState(10);
const [rowCount, setRowCount] = useState(0);
const [loading, setLoading] = useState(false);

We manage the state of the product list, pagination info, and loading status.

3. Fetch Products from Backend


const fetchProducts = async (page, size) => {
  setLoading(true);
  const response = await axios.get('http://localhost:8082/getProducts', {
    params: { page, size }
  });
  setProducts(response.data.content || []);
  setRowCount(response.data.totalElements || 0);
  setLoading(false);
};

We make a GET request to Spring Boot backend using axios. The response gives paginated data.

4. UseEffect Hook


useEffect(() => {
  fetchProducts(pageNumber, pageSize);
}, [pageNumber, pageSize]);

Whenever pageNumber or pageSize changes, fetch new data.

5. DataGrid Configuration


<DataGrid
  rows={products}
  columns={columns}
  pagination
  paginationMode="server"
  rowCount={rowCount}
  pageSizeOptions={[10, 20, 50, 100]}
  loading={loading}
  paginationModel={{ page: pageNumber, pageSize: pageSize }}
  onPaginationModelChange={({ page, pageSize }) => {
    setPageNumber(page);
    setPageSize(pageSize);
  }}
/>

  • paginationMode=”server” tells MUI to not handle pagination internally
  • onPaginationModelChange triggers when the user changes page or size
  • rowCount is the total number of records in DB
  • loading shows a loading spinner while data is fetched

Run you react application

Now when you load your React app, the MUI DataGrid shows only 10 products (or selected size) per page. When you click next/previous, a new request goes to the Spring Boot API with updated page and size.

Aspect Oriented Programming in Spring boot

🔧 Example API Call

When you go to page 2 with size 10, React sends:

GET http://localhost:8082/getProducts?page=1&size=10

Spring Boot returns:

{
  "content": [...],
  "totalElements": 100
}

DataGrid updates automatically!

Benefits of Adding pagination with react and spring boot with DataGrid

  • ⚡ Fast performance even with large datasets
  • 🔄 Real-time backend updates
  • 🔧 Clean pagination experience for users
  • 📱 Fully responsive with Material UI

Conclusion

With just a few lines of code and proper API response, we successfully connected a React Data Grid with Spring Boot backend and implemented server-side pagination. This helps in handling large datasets efficiently.

8 thoughts on “React + Data Grid + Spring Boot With Server-Side Pagination”

  1. I loved as much as youll receive carried out right here The sketch is tasteful your authored material stylish nonetheless you command get bought an nervousness over that you wish be delivering the following unwell unquestionably come more formerly again since exactly the same nearly a lot often inside case you shield this hike

    Reply
  2. Your blog is a breath of fresh air in the often stagnant world of online content. Your thoughtful analysis and insightful commentary never fail to leave a lasting impression. Thank you for sharing your wisdom with us.

    Reply
  3. Your blog is a testament to your passion for your subject matter. Your enthusiasm is infectious, and it’s clear that you put your heart and soul into every post. Keep up the fantastic work!

    Reply

Leave a Comment