R

ReflexKR

Reflex Docs

The Component Workshop: Reflex's 100 Library Components

·

Course overview

Layout

·

Box

·

Flex

·

Stack

·

Grid

·

Container

·

Section

·

Center

·

Spacer

·

Separator

·

Card

·

Inset

·

Aspect Ratio

·

Fragment

Typography

·

Text

·

Heading

·

Link

·

Code

·

Markdown

·

Blockquote

·

Quote

·

Strong

·

Em

·

Kbd

Forms

·

Button

·

Input

·

Text Area

·

Checkbox

·

Switch

·

Radio Group

·

Select

·

Slider

·

Form

·

Upload

Data display

·

Badge

·

Avatar

·

Icon

·

Callout

·

List

·

Data List

·

Code Block

·

Progress

·

Spinner

·

Scroll Area

·

Moment

Disclosure

·

Tabs

·

Accordion

·

Segmented Control

Overlay

·

Tooltip

·

Popover

·

Hover Card

·

Dialog

·

Alert Dialog

·

Drawer

·

Dropdown Menu

·

Context Menu

·

Toast

Dynamic rendering

·

Cond

·

Match

·

Foreach

·

Auto Scroll

Media

·

Image

·

Audio

·

Video

Tables and data grids

·

Table

·

Data Table

·

Data Editor

Charts

·

Area Chart

·

Bar Chart

·

Line Chart

·

Composed Chart

·

Pie Chart

·

Radar Chart

·

Radial Bar Chart

·

Scatter Chart

·

Funnel Chart

·

Treemap

·

Sankey Chart

·

Error Bar

Chart parts

·

Axis

·

Cartesian Grid

·

Chart Tooltip

·

Legend

·

Label

·

Reference

·

Brush

Other chart libraries

·

Plotly

·

Pyplot

HTML elements

·

HTML

·

HTML Text

·

HTML Layout

·

HTML Forms

·

HTML Media

·

HTML Tables

·

SVG

Other tools

·

Theme

·

Skeleton

·

Clipboard

·

Html Embed

·

Script

·

Memo

The Component Workshop: Reflex's 100 Library Components
Tables and data grids

Data Table

rx.data_table

Official docs

Workshop order

Show the product inventory as a table. Customers should be able to search by name, sort by price and page through it five rows at a time.

rx.data_table is a table with search, sorting and pagination built in. You only pass the data and the column names, so it suits showing fixed data quickly. To put buttons in cells or shape the look freely, use Table; to let people edit cells directly, use Data Editor.

Pass a list of rows (a list of lists) to data and a list of column names to columns. With list data, columns is required.

rx.data_table(
    data=[
        ["Avery Bradley", "6-2", 25.0],
        ["Jae Crowder", "6-6", 25.0],
        ["John Holland", "6-5", 27.0],
        ["R.J. Hunter", "6-5", 22.0],
        ["Jonas Jerebko", "6-10", 29.0],
        ["Amir Johnson", "6-9", 29.0],
        ["Jordan Mickey", "6-8", 21.0],
        ["Kelly Olynyk", "7-0", 25.0],
        ["Terry Rozier", "6-2", 22.0],
        ["Marcus Smart", "6-4", 22.0],
    ],
    columns=["Name", "Height", "Age"],
    pagination=True,
    search=True,
    sort=True,
)

Try the props

Four features can be switched on and off. To sort, click a column title; to resize, drag the border of a column title.

Try the props

search

sort

pagination

resizable

rx.data_table(
    data=[
        ["Avery Bradley", "Boston", 25],
        ["Jae Crowder", "Boston", 25],
        ["John Holland", "Boston", 27],
        ["Jonas Jerebko", "Detroit", 29],
        ["Amir Johnson", "Toronto", 29],
        ["Kelly Olynyk", "Miami", 25],
        ["Terry Rozier", "Charlotte", 22],
        ["Marcus Smart", "Memphis", 22],
        ["Isaiah Thomas", "Denver", 27],
        ["Evan Turner", "Portland", 27],
        ["James Young", "Boston", 20],
        ["Tyler Zeller", "Milwaukee", 26],
    ],
    columns=["Name", "Team", "Age"],
    search=True,
    sort=True,
    pagination=True,
    resizable=False,
)
search does a case-insensitive partial match across all columns, and pagination splits rows into pages of 10 by default. Search results are paginated too.
PropValuesUse
datalist of lists, State value, pandas DataFrameRows to show
columnslist of column namesColumn titles. Required for list data; not used together with a DataFrame
searchTrue / FalseSearch box at the top
sortTrue / FalseSort ascending or descending by clicking a column title
paginationTrue / False or dictPagination. Set the rows per page, as in {"limit": 5}
resizableTrue / FalseResize columns by dragging

There are no events of its own. The table is rendered with Grid.js.

Pagination

pagination=True splits rows into pages of 10. To change the rows per page, pass a {"limit": rows} dict to pagination. The dict is handed straight to Grid.js as its pagination settings.

rx.data_table(
    data=[[f"Order #{1000 + i}", ["Paid", "Shipped", "Refunded"][i % 3], 12 + i * 3] for i in range(12)],
    columns=["Order", "Status", "Total"],
    pagination={"limit": 4},
)

Showing data from State

Keep the data and column names in State and the table redraws whenever a handler changes them. Click Add player below to add a row.

class DataTableTeamState(rx.State):
    data: list[list[str]] = [
        ["Lionel", "Messi", "Argentina"],
        ["Cristiano", "Ronaldo", "Portugal"],
        ["Neymar", "Jr", "Brazil"],
        ["Kylian", "Mbappé", "France"],
    ]
    columns: list[str] = ["First Name", "Last Name", "Country"]

    @rx.event
    def add_player(self):
        self.data = self.data + [["Son", "Heung-min", "Korea"]]

    @rx.event
    def reset_players(self):
        self.data = self.data[:4]


rx.vstack(
    rx.hstack(
        rx.button("Add player", on_click=DataTableTeamState.add_player, size="1"),
        rx.button("Reset", on_click=DataTableTeamState.reset_players, size="1", variant="soft"),
    ),
    rx.data_table(
        data=DataTableTeamState.data,
        columns=DataTableTeamState.columns,
        pagination=True,
        search=True,
        sort=True,
    ),
    width="100%",
)

Showing a preset order

To set the initial order, make the sorted list a computed var and pass it to data. When you pass a computed var, always write its return type (-> list[list[str]]). Without it, the table cannot tell the shape of the data and raises an error. Add sort=True as well and users can re-sort by other columns.

class DataTableSortedState(rx.State):
    rows: list[list[str]] = [
        ["Pear", "Fruit"],
        ["Carrot", "Vegetable"],
        ["Apple", "Fruit"],
        ["Basil", "Herb"],
    ]

    @rx.var
    def sorted_rows(self) -> list[list[str]]:
        return sorted(self.rows, key=lambda row: row[0])


rx.data_table(
    data=DataTableSortedState.sorted_rows,
    columns=["Name", "Kind"],
    sort=True,
)

Passing a pandas DataFrame

When you pass a pandas DataFrame to data, the column names come from the DataFrame, so leave out columns (passing both raises an error). pandas is not installed in this course's environment, so this is shown as code only. To try it yourself, install pandas.

import pandas as pd

nba_data = pd.read_csv("data/nba.csv")


def index():
    return rx.data_table(
        data=nba_data[["Name", "Height", "Age"]],
        pagination=True,
        search=True,
        sort=True,
    )


class TableState(rx.State):
    data: pd.DataFrame = pd.read_csv("data/nba.csv")

    @rx.var
    def sorted_data(self) -> pd.DataFrame:
        return self.data.sort_values("Name")

Filling the order

Turn on search, sorting and column resizing for the inventory, and set pagination={"limit": 5} to page through five rows at a time. Keep the price column as numbers so it sorts in numeric order.

rx.data_table(
    data=[
        ["Desk lamp", "Lighting", 39, "In stock"],
        ["Office chair", "Furniture", 189, "Low"],
        ["Monitor arm", "Accessories", 79, "In stock"],
        ["Standing desk", "Furniture", 449, "Sold out"],
        ["Cable tray", "Accessories", 25, "In stock"],
        ["Floor lamp", "Lighting", 89, "Low"],
        ["Bookshelf", "Furniture", 159, "In stock"],
        ["Footrest", "Accessories", 35, "In stock"],
        ["LED strip", "Lighting", 19, "Sold out"],
    ],
    columns=["Product", "Category", "Price ($)", "Stock"],
    search=True,
    sort=True,
    pagination={"limit": 5},
    resizable=True,
)

Workshop notes

  • One call does it: rx.data_table(data=list of lists, columns=column names).

  • Switch search · sort · pagination · resizable on and off. Set rows per page with pagination={"limit": n}.

  • Pass a State value and it redraws when the value changes. Always write the return type of a computed var.

  • When passing a DataFrame, leave out columns (requires pandas).

  • To put components in cells or change the look, use rx.table; to edit, use rx.data_editor.

← Previous

Tables and data grids · Table

Next →

Tables and data grids · Data Editor

Get news about new lessons

We'll email you when this course gets new lessons or a follow-up course opens.

We collect: your email address · Purpose: news about new lessons or the launch of this course · Kept until: you ask us to remove it. We never use it for anything else or share it. Reply to any notice email and we'll delete it right away.

Questions & answers

Ask anything about this lesson. Questions from every language version of this page appear together.

Shown as plain text, without links or formatting.

R

ReflexKR

Learn Python and Reflex by doing. Every example was run and verified on Reflex 0.10.0.

ReflexKR is free, with no banner ads. If it helped you, you can support it with a coffee. ☕ Buy us a coffee

Affiliate disclosure
한국어English日本語简体中文EspañolDeutsch

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex