Tech TutorBangla Web Documentation
Portfolio
HomeHTMLCSSTailwind CSSJavaScriptTypeScriptReactNext.jsNode.jsExpressSocket.IOExpoWordPressPostgreSQLPrismaPostgresNestJSMongoDBDockerTanStackTanStack TableRTK QueryGitGitHub
  • TanStack Table Documentation12টি অধ্যায়
প্রযুক্তি নির্বাচন
HomeHTMLCSSTailwind CSSJavaScriptTypeScriptReactNext.jsNode.jsExpressSocket.IOExpoWordPressPostgreSQLPrismaPostgresNestJSMongoDBDockerTanStackTanStack TableRTK QueryGitGitHub
  • Introduction
  • Installation & Setup
  • Core Concepts
  • Column Definitions
  • Row Models
  • Sorting
  • Filtering
  • Pagination
  • Row Selection
  • Column Management
  • Server-side Mode
  • Advanced Features
  1. Docs
  2. TanStack Table
  3. Sorting — সাজানো
TanStack TableIntermediate

Sorting — সাজানো

sorting state, header-এর toggle, multi-sort, custom sortingFn, sortUndefined, যাচাই করা ও সাধারণ বাগ — বাংলায়।

41টি অংশবাংলা ভাষায়

সাজানো হলো table-এর সবচেয়ে বেশি ব্যবহৃত feature। মূল ব্যাপারটা খুব সহজ — একটা sorting state, একটা row model, আর header-এ একটা button। বাকি সব detail।

তিন লাইনের সেটআপ

সবচেয়ে ছোট sorting setuptsx
tsx
"use client";

import { useState } from "react";
import {
  getCoreRowModel,
  getSortedRowModel,
  useReactTable,
  type SortingState,
} from "@tanstack/react-table";

export function DataTable({ data, columns }: DataTableProps) {
  const [sorting, setSorting] = useState<SortingState>([]);

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),

    state: { sorting },            // ← এই অবস্থা থেকেই সব হবে
    onSortingChange: setSorting,   // ← এখানেই state বদলাবে
  });

  // … rendering
}

sorting state-এর আকার একটা ছোট object-এর array:

type SortDirection = false | "asc" | "desc";
type SortingState = { id: string; desc: boolean }[];

// মানে কী
[]                                    // সাজানো নেই
[{ id: "price", desc: true }]          // মূল্য বড় থেকে ছোট
[{ id: "name", desc: false }]          // নাম অনুক্রমে
const [sorting, setSorting] = useState<SortingState>([
  { id: "price", desc: true },
]);

header-এ সাজানোর button

sortable-header.tsxtsx
tsx
function SortableHeader({
  column,
  children,
}: {
  column: Column<Product>;
  children: React.ReactNode;
}) {
  const direction = column.getIsSorted();

  return (
    <Button
      variant="ghost"
      className="-ml-3 h-8"
      onClick={() => column.toggleSorting(direction === "asc")}
    >
      {children}
      {direction === "asc" && <ArrowUp className="ml-2 size-4" />}
      {direction === "desc" && <ArrowDown className="ml-2 size-4" />}
      {!direction && <ChevronsUpDown className="ml-2 size-4 opacity-50" />}
    </Button>
  );
}

// columns-এ ব্যবহার
{
  accessorKey: "price",
  header: ({ column }) => (
    <SortableHeader column={column}>মূল্য</SortableHeader>
  ),
}

toggleSorting(true) = asc হবে, toggleSorting(false) = desc হবে। false-এর অর্থ "আর সাজাও না"।

getIsSorted-এর তিন অবস্থা

const direction = column.getIsSorted();

// direction === false  → এখনো সাজানো হয়নি
// direction === "asc"  → ছোট থেকে বড়
// direction === "desc" → বড় থেকে ছোট

// বিকল্প — দুটো API
column.getSortDirection();       // "asc" | "desc" | false
column.getIsSorted();           // একই জিনিস

// isSorted বলে এখন এটাই active কিনা
column.getIsSorting();          // boolean
// তিন ধাপের cycle: none → asc → desc → none
onClick={() => column.toggleSorting(
  column.getIsSorted() === "asc",
)}

// শুধু asc/desc, কখনো none নয় — বার বার ক্লিক করলেও কাজ করে
onClick={() => column.toggleSorting(
  column.getIsSorted() === "asc",
  false,  // enableThirdState: false
)}

multi-sort — shift + ক্লিক

বড় টেবিলে সাধারণত একবারে একটাই কলাম সাজায়। কিন্তু মাঝে মাঝে দরকার হয় "এই ক্যাটাগরির ভেতরে মূল্য দেখাও"। ডিফল্টে shift ধরে ক্লিক করলেই multi-sort হয়।

// enabled: true হলে shift-click দিয়ে একাধিক কলাম জোড়া হবে
const [sorting, setSorting] = useState<SortingState>([
  { id: "category", desc: false },
  { id: "price", desc: true },
]);

// ফলাফল: category অনুক্রমে, তার ভেতরে বড় মূল্য আগে

multi-sort-এর অগ্রাধিকার হলো array-এর ক্রম — [0] সবচেয়ে গুরুত্বপূর্ণ। তাই priority বদলাতে অ্যারে সাজিয়ে দিন।

priority বদলানোtsx
tsx
setSorting([
  { id: "category", desc: false }, // ১ম অগ্রাধিকার
  { id: "price", desc: true },     // ২য় অগ্রাধিকার
]);

যাচাই করার উপায়

// যে কলামে ক্লিক করলাম, সেটাই কী সাজানো হচ্ছে
const first = table.getState().sorting[0];
console.log(first?.id, first?.desc ? "desc" : "asc");

// নির্দিষ্ট কলামের অবস্থা
table.getColumn("price").getIsSorted();  // "desc"

// সব sorting মুছে ফেলা
table.resetSorting();
table.setSorting([]);

// ঐচ্ছিক কলাম বাদ দিয়ে সব ফেরত
table.toggleAllColumnsSorted(true);   // সব asc
table.toggleAllColumnsSorted(false);  // সব desc

কোন কলাম sortable নয়

{
  accessorKey: "name",
  header: "নাম",          // ← এখানে কোনো button নেই
  enableSorting: false,
}

{
  id: "actions",
  enableSorting: false,     // ← অ্যাকশন কলাম
}

{
  accessorKey: "createdAt",
  sortingFn: "datetime",     // নিজস্ব comparator
}

enableSorting: false দিলে getSortedRowModel() ওই কলামটা উপেক্ষা করে — header-এ button না দিয়ে state-এও ঢোকানো যায় না।

Custom sortingFn

TanStack ডিফল্ট হিসেবে কয়েকটা comparator দেয়। কিন্তু বাস্তবে বেশিরভাগ ক্ষেত্রে একটা-দুইটা custom লাগেই — বিশেষ করে বাংলা টেক্সট ও নাম সাজানোর জন্য।

custom comparatortypescript
typescript
import {
  type SortingFn,
  type ColumnDef,
} from "@tanstack/react-table";

// রাশির কম্প্যারিশন — আগে/পরে না দেখে
const priceCompare: SortingFn<number> = (a, b, rowA, rowB) =>
  (a ?? 0) - (b ?? 0);

const columns: ColumnDef<Product>[] = [
  {
    accessorKey: "price",
    sortingFn: priceCompare,
  },

  // বাংলা ও ইংরেজি মিলিয়ে সাজানো
  {
    accessorKey: "name",
    sortingFn: (a, b, rowA) =>
      a.localeCompare(b, "bn-BD", { numeric: true, sensitivity: "base" }),
  },

  // stock: কম আগে? বেশি আগে?
  {
    accessorKey: "stock",
    sortingFn: (a, b) => (a ?? 0) - (b ?? 0),
  },
];
import type { SortingFn } from "@tanstack/react-table";

const dateCompare: SortingFn<string> = (a, b) =>
  new Date(a).getTime() - new Date(b).getTime();
বাংলায় sort করার সঠিক উপায়

localeCompare(b, "bn-BD") ব্যবহার করুন, a > b নয়। সাধারণ > দিয়ে সাজালে "আ" < "ক" < "খ" ভুল ক্রমে আসে, আর "10" < "9" হয়ে যায় — কারণ string তুলনা হচ্ছে। localeCompare এগুলো ঠিক করে, সাথে numeric: true দিলে সংখ্যাও ঠিকমতো সাজায়।

sortUndefined — ফাঁকা মান কোথায় যাবে

// null/undefined সবসময় শেষে রাখতে (default)
useReactTable({ sortUndefined: "last" })

// সবসময় প্রথমে
useReactTable({ sortUndefined: "first" })

// অ্যাসাই-সহ ফাঁকা মান আলাদা করে
useReactTable({ sortUndefined: "last" })

এটা বেশিরভাগ ডেটাবেসেই দরকার — rating null হলে সেটা প্রথমে চলে গেলে মনে হয় সবচেয়ে খারাপ item টপে।

URL-এ sorting রাখা

controlled state-এর সবচেয়ে বড় সুবিধা — state যেখানে খুশি রাখা যায়, URL-এও।

"use client";

import { useSearchParams } from "next/navigation";
import { useState } from "react";

export function DataTable({ data, columns }: DataTableProps) {
  const searchParams = useSearchParams();
  const sortParam = searchParams.get("sort"); // "price:desc"

  const [sorting, setSorting] = useState<SortingState>(() =>
    sortParam
      ? [{
          id: sortParam.split(":")[0],
          desc: sortParam.split(":")[1] === "desc",
        }]
      : [],
  );

  const table = useReactTable({
    data,
    columns,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: getSortedRowModel(),
    state: { sorting },
    onSortingChange: (updater) => {
      setSorting(updater);
      // এখানে URL update করুন
    },
  });
}

onSortingChange একটা function পায় (updater) — state আগের মান হলে সেটা, নতুন হলে সেটা। তাই সরাসরি setSorting(updater) লেখা ঠিক, onSortingChange: setSorting-ও কাজ করে।

সাধারণ বাগ

ঘটনাকারণসমাধান
ক্লিক করলেও সাজায় নাgetSortedRowModel() দেওয়া হয়নিrow model যোগ করুন
state বদলায়, কিন্তু UI নড়ে নাstate option দেওয়া হয়নিstate: { sorting } দিন
বাংলা নাম ভুল ক্রমে> ব্যবহার করেছেনlocaleCompare("bn-BD")
"১০" আগে "৯"string তুলনাnumeric: true
নতুন কলাম click করলে পুরোনোটা থাকেmulti-sort চালুshift ছাড়া click করতে হবে
id মিসম্যাচকলাম id বদলেছেন বা id দেননিsorting[0].id ডিবাগে দেখুন
sorting মুছে যায়columns নতুন অ্যারে প্রতি রেন্ডারেcolumns বাইরে সরাসরি রাখুন / useMemo
columns প্রতি রেন্ডারে বানাবেন না

useReactTable-এর ভেতরে const columns = [...] লিখলে প্রতি রেন্ডারে নতুন অ্যারে বানে, table পুরো হিসাব আবার করে এবং state চলে যেতে পারে। columns ফাইলের উপরে export const columns হিসেবে রাখুন অথবা prop হিসেবে parent থেকে পাঠান।

সারসংক্ষেপ

  • sorting: { id, desc }[] + getSortedRowModel() — এটাই সব
  • column.toggleSorting() দিয়ে header-এর cycle
  • shift+click = multi-sort, অ্যারের ক্রমই priority
  • বাংলা ও সংখ্যা সাজাতে localeCompare — > নয়
  • sortUndefined দিয়ে null ঠিক জায়গায় রাখুন

পরবর্তী

সাজানো শেষ। পরের অধ্যায়ে filtering — global search ও column filter, built-in filterFns, আর filter বদলালে সব ভুল যে জায়গায় ঘাটা খেয়ে যায়।

শেষ প্যারায় নিজে practice করুন — কোড কপি করে নিজের এডিটরে চালিয়ে দেখুন।
আগেরRow Model — ডেটার পাইপলাইনপরেরFiltering — খোঁজা ও ছাঁকা
এই পেজে
Tech Tutor

বাংলায় ওয়েব ডেভেলপমেন্ট ডকুমেন্টেশন শিখুন — ধাপে ধাপে।

Homeসব ডকুমেন্টেশনQuick Startআমার নোটস

© 2026 Tech Tutor. বাংলায় শিখুন, বাংলায় গড়ুন।

mdanamolhasan1998@gmail.com