← Back to React Course | Chapter 10: Data Fetching & Async | Lesson 9 of 10

Pagination और Infinite Scroll

Pagination एक book को एक समय में एक page पढ़ने जैसा है पूरी story को एक giant poster पर unfold करने की कोशिश करने के बजाय।
Syntax
markup
const [page, setPage] = useState(1);
const pageSize = 10;
const start = (page - 1) * pageSize;
const pageItems = items.slice(start, start + pageSize);
const totalPages = Math.ceil(items.length / pageSize);

<button disabled={page === 1} onClick={() => setPage(p => p - 1)}>Prev</button>
<button disabled={page === totalPages} onClick={() => setPage(p => p + 1)}>Next</button>

Current Page Track करना

एक simple page state variable (1 से शुरू) track करता है कि data का कौन सा page currently display हो रहा है। इस value को बदलना, आमतौर पर Next/Previous buttons के through, यही है जो dataset का एक अलग slice दिखाना (या fetch करना) trigger करता है।

Note: page state को एक plain number रखें — इसके बारे में reason करना easy है और reset करना simple है।
Warning: जब एक search या filter बदलता है तो page को 1 पर वापस reset करना भूल जाना user को एक filtered result का 'page 5' देखते छोड़ सकता है जिसमें सिर्फ 2 pages हैं।

उदाहरण: Tracking the Current Page

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function App() {
  const [page, setPage] = React.useState(1);
  return (
    <div>
      <p>Current page: {page}</p>
      <button onClick={() => setPage(p => p + 1)}>Next</button>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Client-Side Data को Page के According Slice करना

जब सारा data client पर already load हो गया हो, pagination सिर्फ current page और एक fixed page size के based पर array slice करने की बात है, actually display करने योग्य relevant chunk लेने के लिए Array.slice() उपयोग करते हुए।

Note: Slice indices को (page - 1) * pageSize और page * pageSize के रूप में compute करें।
Warning: यह client-side slicing approach सिर्फ तब काम करता है जब पूरा dataset already load हो — बड़े datasets के लिए, server-side pagination (एक समय में सिर्फ एक page fetch करना) आमतौर पर बेहतर है।

उदाहरण: Slicing Client-Side Data by Page

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function App() {
  const items = Array.from({ length: 23 }, (_, i) => "Item " + (i + 1));
  const [page, setPage] = React.useState(1);
  const pageSize = 5;
  const pageItems = items.slice((page - 1) * pageSize, page * pageSize);
  return (
    <div>
      <ul>{pageItems.map(i => <li key={i}>{i}</li>)}</ul>
      <button onClick={() => setPage(p => p + 1)}>Next</button>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>

Boundaries पर Buttons Disable करना

Total item count और page size से total number of pages compute करना आपको page 1 पर Previous button और last page पर Next button disable करने देता है, users को उन pages पर navigate करने से रोकते हुए जो मौजूद ही नहीं हैं।

Note: Math.ceil(totalItems / pageSize) सही total page count देता है, एक partial final page के लिए round up करते हुए।
Warning: Boundary checks के बिना, last page के बाद repeatedly Next click करना एक empty page दिखाता है बिना items के और बिना यह clear explanation के कि क्यों।

उदाहरण: Disabling Buttons at the Boundaries

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
function App() {
  const items = Array.from({ length: 12 }, (_, i) => "Item " + (i + 1));
  const [page, setPage] = React.useState(1);
  const pageSize = 5;
  const totalPages = Math.ceil(items.length / pageSize);
  return (
    <div>
      <p>Page {page} of {totalPages}</p>
      <button onClick={() => setPage(p => p - 1)} disabled={page === 1}>Prev</button>
      <button onClick={() => setPage(p => p + 1)} disabled={page === totalPages}>Next</button>
    </div>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. सिर्फ current page के बजाय सारे pages upfront fetch करना, pagination के purpose को defeat करते हुए।
  2. जब एक filter या search term बदलता है तो current page को वापस 1 पर reset करना भूल जाना।
  3. Last page पर Next button disable न करना, users को उन pages के लिए request करने देते हुए जो मौजूद नहीं हैं।
चैप्टर सारांश
  • Pagination एक बड़े dataset को pages में split करता है, एक समय में सिर्फ एक page का worth fetch या दिखाते हुए।
  • एक page state variable track करता है कि currently कौन सा page active है।
  • Next/Previous buttons page को increment या decrement करते हैं, आमतौर पर उस page के data के लिए एक fetch फिर से trigger करते हुए।
  • पहले/last page पर navigation buttons disable करना out-of-range pages request करने से रोकता है।
ब्राउज़र सपोर्ट

कोई React-version restriction नहीं — useState और (optionally) एक data-fetching hook से बना।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.