docs/library/dynamic-rendering/foreach.md
import reflex as rx
The rx.foreach component takes an iterable (list, tuple, or dict) and a function that renders each item in the list.
This is useful for dynamically rendering a list of items defined in a state.
# Use `rx.foreach` for state vars; use Python list or dict comprehensions for constants.
class ForeachState(rx.State):
colors: list[str] = [
"#E5484D",
"#12A594",
"#3E63DD",
"#AD5700",
"#F76B15",
"#8E4EC6",
]
def 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",
border="1px solid rgba(0, 0, 0, 0.12)",
box_shadow="0 1px 2px rgba(0, 0, 0, 0.10)",
)
def colored_box(color: rx.Var[str]):
return color_swatch(color, color)
def foreach_example():
return rx.grid(
rx.foreach(ForeachState.colors, colored_box),
columns="2",
)
The function can also take an index as a second argument.
def colored_box_index(color: rx.Var[str], index: rx.Var[int]):
return color_swatch(index, color)
def foreach_example_index():
return rx.grid(
rx.foreach(
ForeachState.colors, lambda color, index: colored_box_index(color, index)
),
columns="2",
)
Nested foreach components can be used to render nested lists.
When indexing into a nested list, it's important to declare the list's type as Reflex requires it for type checking. This ensures that any potential frontend JS errors are caught before the user can encounter them.
class NestedForeachState(rx.State):
numbers: list[list[str]] = [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"]]
def display_row(row: rx.Var[list[str]]):
return rx.hstack(
rx.foreach(
row,
lambda item: rx.box(
item,
border="1px solid black",
padding="0.5em",
),
),
)
def nested_foreach_example():
return rx.vstack(rx.foreach(NestedForeachState.numbers, display_row))
Below is a more complex example of foreach within a todo list.
from dataclasses import dataclass, field
from uuid import UUID, uuid4
@dataclass
class TodoItem:
text: str
id: UUID = field(default_factory=uuid4)
class ListState(rx.State):
items: list[TodoItem] = [
TodoItem(text="Write Code"),
TodoItem(text="Sleep"),
TodoItem(text="Have Fun"),
]
new_item: str = ""
@rx.event
def set_new_item(self, new_item: str):
self.new_item = new_item
@rx.event
def add_item(self):
self.items += [TodoItem(text=self.new_item)]
@rx.event
def finish_item(self, item_id: UUID):
self.items = [item for item in self.items if item.id != item_id]
def get_item(item: rx.Var[TodoItem]):
return rx.list.item(
rx.hstack(
rx.button(
"Done",
on_click=lambda: ListState.finish_item(item.id),
size="1",
variant="soft",
),
rx.text(item.text, font_size="1.25em"),
),
key=item.id,
)
def todo_example():
return rx.vstack(
rx.heading("Todos"),
rx.input(
on_blur=ListState.set_new_item, placeholder="Add a todo...", bg="white"
),
rx.button("Add", on_click=ListState.add_item),
rx.divider(),
rx.list.ordered(
rx.foreach(
ListState.items,
get_item,
),
),
bg="#ededed",
padding="1em",
border_radius="0.5em",
shadow="lg",
)
Items in a dictionary are passed to the render function as key-value pairs.
When iterating over a dict, keys are coerced to strings in the foreach callback, even when the Python dictionary uses another key type.
Using the color example, we can slightly modify the code to use dicts as shown below.
class SimpleDictForeachState(rx.State):
color_chart: dict[int, str] = {1: "#3E63DD", 2: "#E5484D", 3: "#12A594"}
def display_color(color: rx.Var[tuple[str, str]]):
# color is presented as a key-value pair such as ("1", "#3E63DD").
return color_swatch(color[0], color[1])
def foreach_dict_example():
return rx.grid(
rx.foreach(SimpleDictForeachState.color_chart, display_color), columns="2"
)
Now let's show a more complex example with dicts using the color example. This example groups related hex colors in a dictionary and renders both the keys and values as swatches:
class ComplexDictForeachState(rx.State):
color_chart: dict[str, list[str]] = {
"#8E4EC6": ["#E5484D", "#3E63DD"],
"#F76B15": ["#AD5700", "#E5484D"],
"#12A594": ["#3E63DD", "#AD5700"],
}
def display_colors(color: rx.Var[tuple[str, list[str]]]):
return rx.vstack(
color_swatch(color[0], color[0]),
rx.hstack(
rx.foreach(
color[1],
lambda x: color_swatch(x, x),
)
),
align="center",
spacing="2",
)
def foreach_complex_dict_example():
return rx.grid(
rx.foreach(ComplexDictForeachState.color_chart, display_colors),
columns="3",
spacing="4",
)
rx.foreachrx.foreach(iterable, render_fn)
iterable: A state var or iterable to render. Lists, tuples, sets, strings, and dicts are supported; dicts are passed to render_fn as key-value tuples with string keys.render_fn: A function that returns a component for each item. It receives the item as the first rx.Var[...] argument and, optionally, the index as a second rx.Var[int] argument.