R

ReflexKR

Documentación de Reflex

El taller de componentes: los 100 componentes de Reflex

·

Resumen del curso

Diseño

·

Box

·

Flex

·

Stack

·

Grid

·

Container

·

Section

·

Center

·

Spacer

·

Separator

·

Card

·

Inset

·

Aspect Ratio

·

Fragment

Tipografía

·

Text

·

Heading

·

Link

·

Code

·

Markdown

·

Blockquote

·

Quote

·

Strong

·

Em

·

Kbd

Formularios

·

Button

·

Input

·

Text Area

·

Checkbox

·

Switch

·

Radio Group

·

Select

·

Slider

·

Form

·

Upload

Visualización de datos

·

Badge

·

Avatar

·

Icon

·

Callout

·

List

·

Data List

·

Code Block

·

Progress

·

Spinner

·

Scroll Area

·

Moment

Mostrar y ocultar

·

Tabs

·

Accordion

·

Segmented Control

Superposiciones

·

Tooltip

·

Popover

·

Hover Card

·

Dialog

·

Alert Dialog

·

Drawer

·

Dropdown Menu

·

Context Menu

·

Toast

Renderizado dinámico

·

Cond

·

Match

·

Foreach

·

Auto Scroll

Multimedia

·

Image

·

Audio

·

Video

Tablas y cuadrículas de datos

·

Table

·

Data Table

·

Data Editor

Gráficos

·

Area Chart

·

Bar Chart

·

Line Chart

·

Composed Chart

·

Pie Chart

·

Radar Chart

·

Radial Bar Chart

·

Scatter Chart

·

Funnel Chart

·

Treemap

·

Sankey Chart

·

Error Bar

Piezas de gráficos

·

Axis

·

Cartesian Grid

·

Chart Tooltip

·

Legend

·

Label

·

Reference

·

Brush

Otras bibliotecas de gráficos

·

Plotly

·

Pyplot

Elementos HTML

·

HTML

·

HTML Text

·

HTML Layout

·

HTML Forms

·

HTML Media

·

HTML Tables

·

SVG

Otras herramientas

·

Theme

·

Skeleton

·

Clipboard

·

Html Embed

·

Script

·

Memo

El taller de componentes: los 100 componentes de Reflex
Renderizado dinámico

Foreach

Pedido del taller

Crea una lista de tareas. Debe poder añadir tareas nuevas y quitar de la lista las terminadas pulsando 'Done'.

rx.foreach(lista, función) recorre una lista, tupla o dict del State y coloca, para cada elemento, el componente que crea la función. Si la lista cambia, la pantalla se vuelve a dibujar al instante. El for de Python solo se ejecuta una vez, al construir la página, así que no sirve con listas del State.

Para variables del State, rx.foreach; para constantes que no cambian, listas y dicts por comprensión de Python.

#E5484D

#12A594

#3E63DD

#AD5700

#F76B15

#8E4EC6

class ForeachColorState(rx.State):
    colors: list[str] = ["#E5484D", "#12A594", "#3E63DD", "#AD5700", "#F76B15", "#8E4EC6"]


def foreach_color_swatch(label: rx.Var[str | int], color: rx.Var[str]):
    return rx.box(
        rx.text(label, color="white", weight="medium"),
        bg=color,
        padding_y="0.5em",
        padding_x="0.75em",
        min_width="5.5em",
        text_align="center",
        border_radius="0.375rem",
    )


def foreach_colored_box(color: rx.Var[str]):
    return foreach_color_swatch(color, color)


rx.grid(
    rx.foreach(ForeachColorState.colors, foreach_colored_box),
    columns="2",
    spacing="2",
)

El color que recibe la función no es una cadena de Python sino un rx.Var[str]. Por eso puede ir tal cual como hijo o como valor de propiedad (bg=color), pero no admite el if de Python ni métodos de cadena (para condiciones, rx.cond).

Pruébalo tú

rx.foreach no tiene propiedades de aspecto. En su lugar, cambia la lista. Al pulsar un badge se elimina ese elemento, y Add añade uno nuevo. Para pasar el valor del elemento a un evento, escribe on_click=State.remove(f).

applebanana

2 items

FOREACH_FRUIT_POOL = ["apple", "banana", "cherry", "grape", "kiwi", "mango", "pear", "plum"]


class ForeachLiveState(rx.State):
    fruits: list[str] = ["apple", "banana"]

    @rx.event
    def add(self):
        for f in FOREACH_FRUIT_POOL:
            if f not in self.fruits:
                self.fruits.append(f)
                return

    @rx.event
    def remove(self, fruit: str):
        if fruit in self.fruits:
            self.fruits.remove(fruit)

    @rx.event
    def reset_fruits(self):
        self.fruits = ["apple", "banana"]


rx.vstack(
    rx.hstack(
        rx.foreach(
            ForeachLiveState.fruits,
            lambda f: rx.badge(f, rx.icon("x", size=12), on_click=ForeachLiveState.remove(f), cursor="pointer", size="2"),
        ),
        wrap="wrap",
    ),
    rx.hstack(
        rx.button("Add", on_click=ForeachLiveState.add, size="1"),
        rx.button("Reset", on_click=ForeachLiveState.reset_fruits, size="1", variant="soft", color_scheme="gray"),
        rx.text(ForeachLiveState.fruits.length(), " items", size="1", color_scheme="gray"),
        align="center",
    ),
)
ArgumentoValoresUso
Primero (iterable)Var de lista · tupla · dictLista que se recorre. Normalmente una variable del State o una variable calculada
Segundo (render_fn)Función (item) o (item, index)Crea un componente a partir de un elemento. El segundo argumento es la posición, contando desde 0

Recibir también la posición

Si la función recibe dos argumentos, el segundo es la posición (rx.Var[int], desde 0). La muestra de color reutiliza el foreach_color_swatch del primer ejemplo (igual que el ejemplo de dict de más abajo).

0

1

2

3

class ForeachIndexState(rx.State):
    colors: list[str] = ["#E5484D", "#12A594", "#3E63DD", "#AD5700"]


def foreach_colored_box_index(color: rx.Var[str], index: rx.Var[int]):
    return foreach_color_swatch(index, color)


rx.grid(
    rx.foreach(ForeachIndexState.colors, lambda color, index: foreach_colored_box_index(color, index)),
    columns="2",
    spacing="2",
)

Listas anidadas

Si usas otro rx.foreach dentro de rx.foreach, dibujas una lista bidimensional. En ese caso hay que escribir el tipo de la variable del State completo, como list[list[str]]. Reflex necesita conocer el tipo de los elementos interiores para poder recorrer las sublistas, y así detecta el código erróneo antes de que aparezca un error en el navegador.

1
2
3
4
5
6
7
8
9
class ForeachNestedState(rx.State):
    numbers: list[list[str]] = [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]


def foreach_display_row(row: rx.Var[list[str]]):
    return rx.hstack(
        rx.foreach(
            row,
            lambda item: rx.box(item, border=f"1px solid {rx.color('gray', 8)}", padding="0.5em", min_width="2.2em", text_align="center"),
        ),
    )


rx.vstack(rx.foreach(ForeachNestedState.numbers, foreach_display_row))

Recorrer un dict

Si pasas un dict, la función recibe un par (clave, valor). color[0] es la clave y color[1] el valor. Sea cual sea el tipo original de la clave (aquí, int), dentro de la función llega convertida en cadena.

1

2

3

class ForeachSimpleDictState(rx.State):
    color_chart: dict[int, str] = {1: "#3E63DD", 2: "#E5484D", 3: "#12A594"}


def foreach_display_color(color: rx.Var[tuple[str, str]]):
    # color is a key-value pair such as ("1", "#3E63DD").
    return foreach_color_swatch(color[0], color[1])


rx.grid(
    rx.foreach(ForeachSimpleDictState.color_chart, foreach_display_color),
    columns="3",
    spacing="2",
)

Si los valores del dict son listas, se recorren a su vez con rx.foreach. Abajo, bajo cada color clave se colocan los colores que lo acompañan.

#8E4EC6

#E5484D

#3E63DD

#F76B15

#AD5700

#E5484D

#12A594

#3E63DD

#AD5700

class ForeachComplexDictState(rx.State):
    color_chart: dict[str, list[str]] = {
        "#8E4EC6": ["#E5484D", "#3E63DD"],
        "#F76B15": ["#AD5700", "#E5484D"],
        "#12A594": ["#3E63DD", "#AD5700"],
    }


def foreach_display_colors(color: rx.Var[tuple[str, list[str]]]):
    return rx.vstack(
        foreach_color_swatch(color[0], color[0]),
        rx.hstack(rx.foreach(color[1], lambda x: foreach_color_swatch(x, x))),
        align="center",
        spacing="2",
    )


rx.grid(
    rx.foreach(ForeachComplexDictState.color_chart, foreach_display_colors),
    columns="3",
    spacing="4",
)

Constantes con comprensiones de Python

Si la lista es una constante que no cambia, no hace falta rx.foreach. Basta con que Python la recorra una vez al construir la página y despliegue los componentes; además, los elementos son valores reales de Python, así que admiten métodos de cadena e if.

SMLXL
rx.hstack(
    *[rx.badge(size, variant="soft") for size in ["S", "M", "L", "XL"]],
)

Completar el pedido

Las tareas son una lista de dicts {"id", "text"} (como en la documentación oficial, también vale una lista de dataclasses). Si cada elemento lleva key=item["id"], al borrar uno el resto de filas se mantienen tal cual. Done pasa al handler el id de ese elemento, y el handler crea una lista nueva sin ese id. La entrada se recoge con un formulario, así que también se puede añadir con Enter.

Todos

  1. Write Code

  2. Sleep

  3. Have Fun

class ForeachTodoState(rx.State):
    items: list[dict[str, str]] = [
        {"id": "1", "text": "Write Code"},
        {"id": "2", "text": "Sleep"},
        {"id": "3", "text": "Have Fun"},
    ]
    next_id: int = 4

    @rx.event
    def add_item(self, form_data: dict):
        text = form_data.get("new_item", "").strip()[:40]
        if text and len(self.items) < 8:
            self.items = self.items + [{"id": str(self.next_id), "text": text}]
            self.next_id += 1

    @rx.event
    def finish_item(self, item_id: str):
        self.items = [item for item in self.items if item["id"] != item_id]


rx.vstack(
    rx.heading("Todos", size="4"),
    rx.form(
        rx.hstack(
            rx.input(name="new_item", placeholder="Add a todo...", flex="1"),
            rx.button("Add", type="submit"),
            width="100%",
        ),
        on_submit=ForeachTodoState.add_item,
        reset_on_submit=True,
        width="100%",
    ),
    rx.divider(),
    rx.list.ordered(
        rx.foreach(
            ForeachTodoState.items,
            lambda item: rx.list.item(
                rx.hstack(
                    rx.button("Done", on_click=ForeachTodoState.finish_item(item["id"]), size="1", variant="soft"),
                    rx.text(item["text"]),
                    align="center",
                ),
                key=item["id"],
            ),
        ),
    ),
    width="100%",
    max_width="360px",
    padding="1em",
    border_radius="0.5em",
    background=rx.color("gray", 3),
)

Notas del taller

  • rx.foreach(State.lista, función). Para listas constantes, comprensiones de Python.

  • El elemento que recibe la función es un Var. En lugar del if de Python, rx.cond; los valores, con item["key"].

  • Con (item, index) también recibes la posición. Un dict da pares (clave, valor), y la clave se convierte en cadena.

  • En listas anidadas, escribe el tipo completo, como list[list[str]].

  • En listas donde se borra y se añade, da key=valor único.

← Anterior

Renderizado dinámico · Match

Siguiente →

Renderizado dinámico · Auto Scroll

Recibe avisos de nuevas lecciones

Te avisaremos por correo cuando este curso tenga lecciones nuevas o se abra un curso de continuación.

Datos: tu correo electrónico · Finalidad: avisos de nuevas lecciones o de la publicación de este curso · Conservación: hasta que pidas que lo borremos. No lo usamos para nada más ni lo compartimos. Responde a cualquier aviso y lo borraremos enseguida.

Preguntas y respuestas

Pregunta lo que quieras sobre esta lección. Aquí se reúnen las preguntas de todas las versiones de idioma de esta página.

Se muestra como texto plano, sin enlaces ni formato.

R

ReflexKR

Aprende Python y Reflex haciendo. Todos los ejemplos se ejecutaron y verificaron en Reflex 0.10.0.

ReflexKR es gratis y sin banners publicitarios. Si te ayudó, puedes apoyarlo con un café. ☕ Invítanos un café

Aviso de afiliados
한국어English日本語简体中文EspañolDeutsch

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

Built with Reflex