Reflex Logo

Intro

Gallery

Hosting

Components

New

Learn

Components

API Reference

Onboarding

Vars

/

Base-vars

Vars are any fields in your app that may change over time. A Var is directly rendered into the frontend of the app.

Base vars are defined as fields in your State class.

They can have a preset default value. If you don't provide a default value, you must provide a type annotation.

AAPL
$150
increased by4%
class TickerState(rx.State):
    ticker: str = "AAPL"
    price: str = "$150"


def ticker_example():
    return rx.chakra.stat_group(
        rx.chakra.stat(
            rx.chakra.stat_label(TickerState.ticker),
            rx.chakra.stat_number(TickerState.price),
            rx.chakra.stat_help_text(
                rx.chakra.stat_arrow(type_="increase"),
                "4%",
            ),
        ),
    )

In this example ticker and price are base vars in the app, which can be modified at runtime.

State is just a python class and so can be defined on one page and then imported and used on another. Below we define TickerState class on the page state.py and then import it and use it on the page index.py.

# state.py


class TickerState(rx.State):
    ticker: str = "AAPL"
    price: str = "$150"
# index.py
from .state import TickerState


def ticker_example():
    return rx.chakra.stat_group(
        rx.chakra.stat(
            rx.chakra.stat_label(TickerState.ticker),
            rx.chakra.stat_number(TickerState.price),
            rx.chakra.stat_help_text(
                rx.chakra.stat_arrow(type_="increase"),
                "4%",
            ),
        ),
    )

Any Var in a state class that starts with an underscore is considered backend only and will not be syncronized with the frontend. Data associated with a specific session that is not directly rendered on the frontend should be stored in a backend-only var to reduce network traffic and improve performance.

They have the advantage that they don't need to be JSON serializable, however they must still be cloudpickle-able to be used with redis in prod mode. They are not directly renderable on the frontend, and may be used to store sensitive values that should not be sent to the client.

For example, a backend-only var is used to store a large data structure which is then paged to the frontend using cached vars.

Page 1 / 10

Page Size

    _backend[0] = 80

    _backend[1] = 10

    _backend[2] = 38

    _backend[3] = 10

    _backend[4] = 76

    _backend[5] = 82

    _backend[6] = 62

    _backend[7] = 42

    _backend[8] = 75

    _backend[9] = 100

import numpy as np


class BackendVarState(rx.State):
    _backend: np.ndarray = np.array(
        [random.randint(0, 100) for _ in range(100)]
    )
    offset: int = 0
    limit: int = 10

    @rx.cached_var
    def page(self) -> list[int]:
        return [
            int(x)  # explicit cast to int
            for x in self._backend[
                self.offset : self.offset + self.limit
            ]
        ]

    @rx.cached_var
    def page_number(self) -> int:
        return (
            (self.offset // self.limit)
            + 1
            + (1 if self.offset % self.limit else 0)
        )

    @rx.cached_var
    def total_pages(self) -> int:
        return len(self._backend) // self.limit + (
            1 if len(self._backend) % self.limit else 0
        )

    def prev_page(self):
        self.offset = max(self.offset - self.limit, 0)

    def next_page(self):
        if self.offset + self.limit < len(self._backend):
            self.offset += self.limit

    def generate_more(self):
        self._backend = np.append(
            self._backend,
            [
                random.randint(0, 100)
                for _ in range(random.randint(0, 100))
            ],
        )


def backend_var_example():
    return rx.vstack(
        rx.hstack(
            rx.button(
                "Prev",
                on_click=BackendVarState.prev_page,
            ),
            rx.text(
                f"Page {BackendVarState.page_number} / {BackendVarState.total_pages}"
            ),
            rx.button(
                "Next",
                on_click=BackendVarState.next_page,
            ),
            rx.text("Page Size"),
            rx.chakra.number_input(
                width="5em",
                value=BackendVarState.limit,
                on_change=BackendVarState.set_limit,
            ),
            rx.button(
                "Generate More",
                on_click=BackendVarState.generate_more,
            ),
        ),
        rx.list(
            rx.foreach(
                BackendVarState.page,
                lambda x, ix: rx.text(
                    f"_backend[{ix + BackendVarState.offset}] = {x}"
                ),
            ),
        ),
    )
← OverviewComputed Vars →

Did you find this useful?