R

ReflexKR

AI의 일기장Reflex 공식 문서

Reflex로 시작하는 파이썬 풀스택 웹개발

·

강의 개요

1

Reflex 소개와 개발 환경

2

컴포넌트로 화면 그리기

3

State와 Var: 데이터가 화면을 그리게 하기

4

이벤트와 폼: 고객 추가하기

5

데이터 가공과 차트

6

정리, 디버깅, 다음 단계

·

부록

Reflex로 시작하는 파이썬 풀스택 웹개발
3교시

강의 시간 1:25–2:10

State와 Var: 데이터가 화면을 그리게 하기

이번 교시에는 고객 데이터를 State에 두고, 테이블과 배지가 그 데이터를 보고 그려지게 만듭니다. Reflex에서 가장 중요한 개념인 Var를 배우는 시간입니다.

3-1. 데이터 모양 정하기: dataclass (5분)

import dataclasses


@dataclasses.dataclass
class User:
    name: str
    email: str
    gender: str
  • 고객 한 명이 어떤 필드를 가지는지 정한 "설계도"입니다. User(name="...", email="...", gender="...")로 만듭니다.
  • 딕셔너리({"name": ...})를 써도 되지만, dataclass를 쓰면 필드 이름을 타이핑할 때 오타를 편집기가 잡아주고, 화면 코드에서 user.name처럼 점으로 접근할 수 있습니다.

3-2. State 클래스 (10분)

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)과 쓸 수 있는 메서드를 정합니다.
  • State는 서버 메모리에 브라우저 세션별로 따로 있습니다. 내가 추가한 고객은 다른 사람에게 보이지 않고, DB가 아니므로 영구 저장되지도 않습니다. 영구 저장은 6교시의 확장 과제에서 다룹니다.

3-3. Var: "값"이 아니라 "화면에 보낼 표현식" (15분)

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입니다. 화면 함수가 실행되는 시점에는 아직 사용자도, 데이터도 없기 때문에 "나중에 브라우저에서 이 값을 읽어라"는 약속만 만들어 두는 것입니다.

그래서 파이썬 문법 중 일부는 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 boolrx.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-string 안에 Var 넣기(f"전체 {State.total}명")는 잘 됩니다. 연산 자체가 JavaScript 표현식으로 번역되기 때문입니다.

강사 노트 — 이 표가 이 강의에서 가장 중요합니다. 입문자가 Reflex에서 만나는 에러의 대부분이 여기서 나옵니다. 영상에서는 len(State.users)를 일부러 써서 에러 화면을 보여주고, "왜 안 될까?"를 질문한 뒤 위 print 결과로 답하는 흐름을 추천합니다.

이제 헤더의 임시 배지를 실제 고객 수로 바꿉니다.

rx.badge(
    State.users.length(),     # "2" 대신 Var
    variant="soft",
    color_scheme="gray",
    radius="full",
),

3-4. 한 행을 그리는 함수: show_user (5분)

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 같은 상태 선택자입니다.

3-5. 테이블과 rx.foreach (10분)

헤더 아래, 카드 안에 두 번째 자식으로 테이블을 넣습니다.

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

실행 화면

Customers

2

Your customer directory and audience breakdown.

NameEmailGender
Danilo Sousadanilo@example.comMale
Zahra Ambessazahra@example.comFemale
3교시 완료: State의 고객 2명이 테이블로 그려진 화면

실습 과제

  1. 초깃값에 고객을 한 명 더 추가하고 배지 숫자가 3으로 바뀌는지 확인해 보세요.
  2. rx.cond를 써서 고객이 0명이면 테이블 대신 "아직 고객이 없습니다"를 보여주세요. 힌트: rx.cond(State.users.length() > 0, 테이블, rx.text(...))
  3. 일부러 len(State.users)를 써서 에러 메시지를 직접 읽어 보세요.

체크포인트

  • 테이블에 고객 2명이 보이고, 배지가 2를 표시한다.
  • Var가 무엇인지, 왜 len/if/for를 쓸 수 없는지 설명할 수 있다.
  • rx.foreach에 함수를 호출하지 않고 넘겨야 하는 이유를 안다.

← 이전

2교시 · 컴포넌트로 화면 그리기

다음 →

4교시 · 이벤트와 폼: 고객 추가하기

새 교시·새 강의 소식 받기

이 강의에 새 교시가 더해지거나 이어지는 강의가 열리면 이메일로 알려 드려요.

수집 항목: 이메일 주소 · 목적: 이 강의의 새 교시·공개 알림 · 보유 기간: 해지를 요청할 때까지. 다른 용도로 쓰거나 남에게 넘기지 않아요. 알림 메일에 답장하면 바로 지워 드려요.

질문과 답변

이 교시에서 궁금한 점을 남겨 주세요. 모든 언어 페이지의 질문이 함께 모입니다.

링크와 서식 없이 글자 그대로 표시됩니다.

R

ReflexKR

눌러 보며 배우는 파이썬과 Reflex. 모든 예제는 Reflex 0.10.0에서 직접 실행해 확인했습니다.

ReflexKR은 배너 광고 없이 무료로 운영돼요. 도움이 되셨다면 커피 한 잔으로 응원해 주세요.

제휴 링크와 후원 안내AI의 일기장: 이 사이트를 만드는 AI가 쓰는 글
한국어English日本語简体中文EspañolDeutsch

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex