説明の前に、まずは押してみましょう。下のボタンを押すと数字が1ずつ増えます。この回を終えるころには、この10行ほどのコードがどう動いているのかを説明できるようになります。
import reflex as rx
class CounterState(rx.State):
count: int = 0
@rx.event
def increment(self):
self.count += 1
def counter_increment():
return rx.hstack(
rx.heading(CounterState.count, as_="h2"),
rx.button("Increment", on_click=CounterState.increment),
)localhost:3000
操作してみようコードは3つの部分に分かれています。
| 部分 | コード | 役割 |
|---|---|---|
| State | class CounterState(rx.State) | 変化するデータ(count)を入れておく箱 |
| イベントハンドラ | def increment(self) | データを変更する関数 |
| イベントトリガー | on_click=CounterState.increment | 「押されたらこの関数を呼ぶ」というつなぎ |
ボタンを押すとincrementがサーバーで実行され、countが変わると、Reflexがその値を使っている部分の画面だけを自動で描き直します。画面を直接書き換えるコードは1行もありません。
アプリには、時間とともに変化するデータがあります。カウンターの数字、ログインしているかどうか、カートの中身などです。Reflexでは、こうしたデータをStateクラスに入れておきます。
rx.Stateを継承したクラスを作り、その中に変数を書きます。この変数をVar(state var)と呼びます。count: int)、初期値を与えることもできます(= 0)。画面でVarを使うときは、MyState.countのようにクラス名で参照します。子要素として入れても、propsの値として渡しても構いません。
class MyState(rx.State):
count: int = 0
color: str = "red"
def counter():
return rx.hstack(
# The heading `color` prop is set to the `color` var in MyState.
rx.heading("Count: ", as_="h2", color=MyState.color),
# The `count` var in `MyState` is passed as a child to the heading component.
rx.heading(MyState.count, as_="h2"),
)localhost:3000
実行画面同じVarを複数のコンポーネントで使っても大丈夫です。値が変わると、そのVarを使っている箇所がすべて一緒に変わります。
ポイント — Stateを変更できるのはイベントハンドラだけです。画面のコードでMyState.count = 5のように直接値を代入することはできません。
State内に定義したメソッドのうち、データを変更するものをイベントハンドラと呼びます。on_clickのようにコンポーネントが持つ特別なpropsをイベントトリガーと呼び、トリガーとハンドラをつなぐと、画面がユーザーの操作に反応するようになります。
ハンドラの上の@rx.eventは、必ず付けることをおすすめします。このデコレーターがあると、エディタや型チェッカーが「このハンドラに引数をいくつ、どんな型で渡すべきか」を確認してくれるので、ミスを事前に防げます。
ハンドラも普通の関数と同じように引数を受け取れます。1ずつ増やすボタンと5ずつ増やすボタンを、1つのハンドラで作ってみましょう。
class CounterState2(rx.State):
count: int = 0
@rx.event
def increment(self, amount: int):
self.count += amount
def counter_variable():
return rx.hstack(
rx.heading(CounterState2.count, as_="h2"),
rx.button("Increment by 1", on_click=lambda: CounterState2.increment(1)),
rx.button("Increment by 5", on_click=lambda: CounterState2.increment(5)),
)localhost:3000
操作してみようlambda: CounterState2.increment(1)のようにlambdaで包んで、「押されたら1を渡して呼ぶ」という意図をはっきりさせています。on_click=CounterState2.increment(1)のように直接書いても、まったく同じように動きます。このコードはハンドラをその場で実行するのではなく、「押されたらamount=1で実行する」というイベント情報を作っておくだけです。ハンドラのコードは、ボタンが押されたときにサーバーで実行されます。on_clickはハンドラに何も値を渡しませんが、値を渡してくれるトリガーもあります。on_blurは、入力欄からフォーカスが外れたとき(ほかの場所をクリックしたり、Tabキーを押したりしたとき)に、入力された文字列をハンドラに渡します。
class TextState(rx.State):
text: str = ""
@rx.event
def update_text(self, new_text: str):
self.text = new_text
def text_input():
return rx.vstack(
rx.heading(TextState.text, as_="h2"),
rx.input(default_value=TextState.text, on_blur=TextState.update_text),
)localhost:3000
操作してみようポイント — ハンドラの引数の数は、トリガーが渡す値の数と一致している必要があります。on_blurは値を1つ渡すので、update_textもnew_textを1つ受け取ります。数が合わないとエラーになります。
CounterStateにdecrementハンドラを追加し、数字を1ずつ減らすボタンを作ってみましょう。counter_variableに「Reset」ボタンを追加して、countを0に戻してみましょう。引数を受け取るハンドラで作れるでしょうか?on_blurの代わりにon_changeを使ってみましょう。文字を入力するたびに見出しが変わります。クラス名.変数名で参照できる。on_clickに引数付きでハンドラをつないでも、ハンドラがすぐには実行されない理由がわかる。新しい授業・講座のお知らせを受け取る
この講座に授業が追加されたり、続きの講座が公開されたりしたらメールでお知らせします。
R
ReflexKR
触って学ぶPythonとReflex。すべての例はReflex 0.10.0で実際に動かして確認しています。
ReflexKRはバナー広告なし・無料で運営しています。役に立ったら、コーヒー一杯で応援してください。 ☕ コーヒーで応援する
アフィリエイトと支援について© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
質問と回答
この回について気になることを書き込んでください。すべての言語のページの質問がここに集まります。