この時限では、顧客データをStateに置き、テーブルとバッジがそのデータをもとに描画されるようにします。Reflexでいちばん重要な概念であるVarを学ぶ時間です。
import dataclasses
@dataclasses.dataclass
class User:
name: str
email: str
gender: strUser(name="...", email="...", gender="...")のように作ります。{"name": ...})を使ってもかまいませんが、dataclassにしておくと、フィールド名の打ち間違いをエディタが指摘してくれますし、画面のコードでuser.nameのようにドットでアクセスできます。class State(rx.State):
users: list[User] = [
User(name="Danilo Sousa", email="danilo@example.com", gender="Male"),
User(name="Zahra Ambessa", email="zahra@example.com", gender="Female"),
]rx.Stateを継承したクラスのクラス変数が、状態変数(state var)になります。ここに書いた値は初期値です。: list[User])は必須です。Reflexは型を見て、ブラウザに送る形式(JSON)や使えるメソッドを決めます。1限目で「画面の関数はアプリの起動時に一度だけ実行される」と説明しました。では、画面の関数の中でState.usersを使うと何が得られるのでしょうか。実際に出力してみるとこうなります。
>>> type(State.users).__name__
'ArrayCastedVar'
>>> print(State.users.length())
reflex___state____state__tutorial_261019___tutorial_261019____state.users_rx_state_.length出てくるのは顧客のリストではなく、JavaScriptの式です。これがVarです。画面の関数が実行される時点では、まだユーザーもデータも存在しません。そのため、「あとでブラウザでこの値を読み取ってね」という約束だけを作っておくのです。
そのため、Pythonの文法の一部はVarに対して使えません。Reflex 0.10で実際に出るエラーと、その代わりの書き方は次のとおりです。
| やりたいこと | 動かないコード | 出るエラー | Reflexでの書き方 |
|---|---|---|---|
| 個数を数える | len(State.users) | TypeError: object of type 'ArrayCastedVar' has no len() | State.users.length() |
| 条件分岐 | "a" if State.n > 1 else "b" | VarTypeError: Cannot convert Var ... to bool | rx.cond(State.n > 1, "a", "b") |
| 繰り返し | for u in State.users: | VarTypeError: Cannot iterate over Var ... | rx.foreach(State.users, show_user) |
| 複雑な加工 | 画面の関数の中で計算 | — | イベントや@rx.var(computed var)で計算 |
逆に、Var同士の比較や算術(State.page + 1)、f文字列にVarを埋め込むこと(f"合計 {State.total}人")は問題なく使えます。演算そのものがJavaScriptの式に変換されるからです。
講師メモ — この表が講座全体でいちばん重要です。初心者がReflexで遭遇するエラーのほとんどはここから生まれます。動画では、わざとlen(State.users)と書いてエラー画面を見せ、「なぜ動かないのでしょう?」と問いかけてから、上のprintの結果で答える流れがおすすめです。
では、ヘッダーの仮のバッジを実際の顧客数に置き換えましょう。
rx.badge(
State.users.length(), # "2"の代わりにVar
variant="soft",
color_scheme="gray",
radius="full",
),def show_user(user: User):
return rx.table.row(
rx.table.cell(user.name),
rx.table.cell(user.email),
rx.table.cell(user.gender),
style={"_hover": {"bg": rx.color("gray", 3)}},
align="center",
)Userと書きましたが、実際に渡されるのはUserを指すVarです。user.nameも「この行の顧客のnameを読み取れ」という式になります。dataclassでフィールドを宣言してあるおかげで、ドットでアクセスできます。style={"_hover": {...}}は、マウスを乗せたときのスタイルです。_hoverや_focusのように_で始まるキーは、CSSの:hoverのような状態セレクタにあたります。ヘッダーの下、カードの中の2番目の子要素としてテーブルを入れます。
rx.box(
rx.table.root(
rx.table.header(
rx.table.row(
rx.table.column_header_cell("Name"),
rx.table.column_header_cell("Email"),
rx.table.column_header_cell("Gender"),
)
),
rx.table.body(rx.foreach(State.users, show_user)),
variant="ghost",
size="3",
width="100%",
),
overflow_x="auto", # 狭い画面では横スクロール
width="100%",
border_top=f"1px solid {rx.color('slate', 4)}",
border_bottom=f"1px solid {rx.color('slate', 4)}",
padding_x="12px",
),root > header(見出し行)+body(データ行)> row > cell。HTMLの<table>、<thead>、<tbody>、<tr>、<td>に対応します。rx.foreach(リストのVar, 関数)は、ブラウザ側でリストの各要素に関数を適用します。関数は呼び出さずに名前だけを渡します(show_user()ではなくshow_user)。forを使ってもかまいません。コンパイル時に値が決まっているからです。例:*[rx.table.column_header_cell(h) for h in ["Name", "Email", "Gender"]]ブラウザで確認 — カードの中に顧客2人分のテーブルができ、バッジの2はState.users.length()から来るようになりました。行にマウスを乗せると、背景が薄いグレーに変わります。
localhost:3000
実行画面Your customer directory and audience breakdown.
rx.condを使って、顧客が0人のときはテーブルの代わりに「まだ顧客がいません」と表示してみましょう。ヒント:rx.cond(State.users.length() > 0, テーブル, rx.text(...))len(State.users)と書いて、エラーメッセージを実際に読んでみましょう。len/if/forが使えないのかを説明できる。rx.foreachに関数を呼び出さずに渡す理由がわかる。新しい授業・講座のお知らせを受け取る
この講座に授業が追加されたり、続きの講座が公開されたりしたらメールでお知らせします。
R
ReflexKR
触って学ぶPythonとReflex。すべての例はReflex 0.10.0で実際に動かして確認しています。
ReflexKRはバナー広告なし・無料で運営しています。役に立ったら、コーヒー一杯で応援してください。 ☕ コーヒーで応援する
アフィリエイトと支援について© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
質問と回答
この回について気になることを書き込んでください。すべての言語のページの質問がここに集まります。