この時限では、状態を持たない固定の画面だけを作ります。終わるころには、角の丸いカードの中に「Customers」というタイトルと説明文が入ったヘッダーが表示されます。
tutorial_261019/ # プロジェクトのルート(ここでreflexコマンドを実行)
├── rxconfig.py # アプリ名とプラグインの設定
├── pyproject.toml / uv.lock # Pythonの依存関係(uvが管理)
├── assets/ # 画像などの静的ファイル → "/favicon.ico"のように参照
├── reflex.lock/ # 画面側パッケージのロックファイル(コミット対象)
├── .web/ # コンパイルされたReactコード(自動生成、編集禁止)
└── tutorial_261019/ # app_nameと同じ名前のPythonパッケージ
├── __init__.py
└── tutorial_261019.py # これから作業するファイル (app = rx.App())rxconfig.pyは次のとおりです。app_nameが内側のフォルダ名と一致していないと、Reflexはアプリを見つけられません。
import reflex as rx
config = rx.Config(
app_name="tutorial_261019",
plugins=[
rx.plugins.SitemapPlugin(),
rx.plugins.TailwindV4Plugin(),
rx.plugins.RadixThemesPlugin(), # ボタンやテーブルなどの基本デザインを提供
],
)tutorial_261019/tutorial_261019.pyの中身をすべて消して、次のように書き始めます。
import reflex as rx
def index() -> rx.Component:
return rx.heading("Customers")
app = rx.App()
app.add_page(index, title="Customer Data App")index()は画面の部品(コンポーネント)を返す関数です。1ページ=1関数です。app = rx.App()は、モジュールのトップレベルに必ず置きます。Reflexはこの変数名でアプリを探します。add_page(index)は、関数名がindexなのでルートパス/に登録されます。titleはブラウザのタブに表示されるタイトルです。ブラウザで確認 — 保存すると、左上に「Customers」というタイトルだけが表示されます。余白がないので画面の端にくっついていますが、これで正常です。
localhost:3000
実行画面Reflexの画面コードは、実質この2つのルールがすべてです。
size="6"、margin="0"のように名前=値の形で指定します。rx.box( # <div>
rx.heading("Customers", size="6"), # 子要素 1
rx.badge("2"), # 子要素 2
display="flex", # スタイル
gap="12px",
)align-items → align_items、margin-top → margin_top。_を付けます。as → as_、type → type_。rx.color("slate", 11)はRadixのカラーパレットです。数字が大きいほど濃くなり、ダークモードでも自動的に調整されます。1~2は背景、4~6は枠線、11~12は文字によく使います。講師メモ — 「HTMLタグを関数呼び出しに置き換えたもの」と説明すると、すぐに理解してもらえます。rx.box = <div>、rx.text = <p>、rx.heading = <h1>~<h6>。ブラウザの開発者ツール(F12)で、実際に生成されたタグを見せてください。
ヘッダーは左側(タイトル+バッジ+説明)と右側(ボタン)に分かれます。ボタンは4限目で追加するので、今は左側だけを作ります。
def index() -> rx.Component:
return rx.box(
rx.box(
rx.box(
rx.heading("Customers", size="6", as_="h3", margin="0"),
rx.badge("2", variant="soft", color_scheme="gray", radius="full"),
display="flex",
align_items="center",
gap="12px",
),
rx.text(
"Your customer directory and audience breakdown.",
size="2",
color=rx.color("slate", 11),
margin_top="6px",
),
),
display="flex",
align_items="center",
justify_content="space-between",
flex_wrap="wrap",
gap="16px",
padding="24px",
)"2"は仮の値です。3限目でState.users.length()に置き換えて、実際の顧客数を表示します。justify_content="space-between"は、子要素を両端に振り分けます。ボタンが右端に寄るのはこのためです。flex_wrap="wrap"は、画面が狭いときにボタンを次の行へ折り返します(モバイル対応)。ブラウザで確認 — タイトルの横にグレーの丸いバッジ(2)、その下にグレーの説明文が表示されます。カードの枠線はまだありません。
localhost:3000
実行画面Your customer directory and audience breakdown.
ヘッダーをもう一度rx.boxで包んで、カードの形にします。この外側のボックスがアプリ全体の枠になり、このあとテーブルやチャートが順番にこの中へ入っていきます。
def index() -> rx.Component:
return rx.box(
header, # 2-4で作ったヘッダーのbox
# テーブル(3限目)、チャート(5限目)がここに追加される
width="100%",
min_width="0",
max_width="64em", # カードの最大幅
margin_x="auto", # 中央寄せ
margin_y="24px",
border=f"1px solid {rx.color('slate', 5)}",
border_radius="16px",
background=rx.color("slate", 1),
overflow="hidden", # 中身が角丸の外にはみ出すのを防ぐ
box_shadow="0 4px 24px rgba(0, 0, 0, 0.03)",
style={
"& *": {"box_sizing": "border-box"},
"& p, & h3": {"text_align": "left"},
},
)style={...}は、キーワード引数では表しにくいCSSセレクタを使うときに使います。"& *"は「このボックスの中のすべての要素」という意味です。rx.color(...)を使えます。シングルクォートとダブルクォートの使い分けに注意してください。ブラウザで確認 — ヘッダーが角の丸いカードの中に収まり、カードが画面の中央に配置されます。ブラウザのウィンドウを狭くすると、カードの幅も一緒に縮みます。
localhost:3000
実行画面Your customer directory and audience breakdown.
border_radiusを"4px"と"32px"に変えて、違いを比べてみましょう。rx.color_mode.button()をヘッダーに追加し、ダークモードでも色が自然に切り替わるか確認してみましょう。新しい授業・講座のお知らせを受け取る
この講座に授業が追加されたり、続きの講座が公開されたりしたらメールでお知らせします。
R
ReflexKR
触って学ぶPythonとReflex。すべての例はReflex 0.10.0で実際に動かして確認しています。
ReflexKRはバナー広告なし・無料で運営しています。役に立ったら、コーヒー一杯で応援してください。 ☕ コーヒーで応援する
アフィリエイトと支援について© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
質問と回答
この回について気になることを書き込んでください。すべての言語のページの質問がここに集まります。