2교시에는 if 대신 rx.cond를, 3교시에는 for 대신 rx.foreach를 썼습니다. 파이썬인데 왜 파이썬 문법을 그대로 못 쓸까요? 이번 교시에 그 이유를 풀면, Reflex에서 만나는 에러의 대부분이 왜 생기는지 한 번에 이해할 수 있습니다.
Reflex 앱의 코드는 서로 다른 두 시점에 실행됩니다.
| 컴파일 타임 | 런타임 | |
|---|---|---|
| 언제 | 앱을 켤 때 한 번 | 앱이 도는 동안 계속 |
| 무엇이 | 화면 함수 (show_login, render_item …) | 이벤트 핸들러 (increment, toggle_login …) |
| 어디서 | 파이썬 코드가 JavaScript(React) 코드로 바뀜 | 서버의 파이썬 |
| State 값 | 아직 모름 | 진짜 값이 있음 |
화면 함수는 앱을 켤 때 JavaScript로 번역되어 브라우저로 보내집니다. 번역할 때는 아직 어떤 사용자가 무엇을 누를지 모르므로, 화면 함수 안의 LoginState.logged_in은 진짜 True/False가 아니라 "나중에 브라우저에서 채워질 자리"입니다. 이 자리가 바로 Var입니다.
반대로 이벤트 핸들러는 번역되지 않고 서버에서 파이썬 그대로 실행됩니다. 그래서 핸들러 안에서는 어떤 파이썬 코드나 라이브러리든 쓸 수 있습니다.
아래 핸들러는 if도 쓰고, State 바깥에 정의한 함수도 부릅니다. 런타임에 서버에서 실행되므로 문제없습니다.
def check_even(num: int):
return num % 2 == 0
class MyState3(rx.State):
count: int = 0
text: str = "even"
@rx.event
def increment(self):
# Use any Python code within state.
# Even reference functions defined outside the state.
if check_even(self.count):
self.text = "even"
else:
self.text = "odd"
self.count += 1
def count_and_check():
return rx.box(
rx.heading(MyState3.text, as_="h2"),
rx.button("Increment", on_click=MyState3.increment),
)localhost:3000
직접 눌러 보세요화면 함수 안에서도 파이썬을 쓸 수는 있습니다. 단, 컴파일 타임에 이미 값이 정해진 것(State var를 쓰지 않는 것)에만 쓸 수 있습니다. 아래 range(5)와 check_even(i)는 앱을 켤 때 계산이 끝납니다.
def show_numbers():
return rx.vstack(*[rx.text(f"{i} is {'even' if check_even(i) else 'odd'}") for i in range(5)])localhost:3000
실행 화면0 is even
1 is odd
2 is even
3 is odd
4 is even
State var는 컴파일 타임에 값을 모르므로, 화면 함수 안에서 아래 코드는 모두 에러가 납니다.
if로 Var 값 따지기: 값이 참인지 거짓인지 아직 모릅니다. props 값을 고를 때도 마찬가지입니다.
class BadState(rx.State):
count: int = 0
def count_if_even():
return rx.box(
rx.heading("Count: ", as_="h2"),
# This will raise a compile error, as BadState.count is a var and not known at compile time.
rx.text(BadState.count if BadState.count % 2 == 0 else "Odd"),
# Using an if statement with a var as a prop will NOT work either.
rx.text("hello", color="red" if BadState.count % 2 == 0 else "blue"),
)for로 리스트 Var 돌기: 항목이 몇 개일지 아직 모릅니다.
class BadState(rx.State):
items: list[str] = ["Apple", "Banana", "Cherry"]
def loop_over_list():
return rx.box(
# This will raise a compile error, as BadState.items is a list and not known at compile time.
*[rx.text(item) for item in BadState.items]
)len() 같은 파이썬 함수에 Var 넣기: 글자 수를 셀 문자열이 아직 없습니다.
class BadTextState(rx.State):
text: str = "Hello world"
def format_text():
return rx.box(
# Python operations such as `len` will not work on state vars.
rx.text(len(BadTextState.text)),
)그러면 화면에서 "짝수면 Even, 홀수면 Odd"는 어떻게 보여줄까요? Reflex는 Var에 쓸 수 있는 Var 연산을 준비해 두었습니다. %, ==, > 같은 연산자를 Var에 쓰면 계산 결과도 Var가 되고, 실제 계산은 브라우저에서 값이 들어온 뒤에 일어납니다.
class CountEvenState(rx.State):
count: int = 0
@rx.event
def increment(self):
self.count += 1
def count_if_even():
return rx.box(
rx.heading("Count: ", CountEvenState.count, as_="h2"),
rx.cond(
# Here we use the `%` and `==` var operations to check if the count is even.
CountEvenState.count % 2 == 0,
rx.text("Even"),
rx.text("Odd"),
),
rx.button("Increment", on_click=CountEvenState.increment),
)localhost:3000
직접 눌러 보세요Even
이제 1~3교시에 쓴 도구가 왜 필요했는지 한 표로 정리됩니다.
| 하고 싶은 것 | 화면 코드에서 안 됨 | 대신 쓰는 것 |
|---|---|---|
| 조건에 따라 다른 화면 | if / else | rx.cond(조건, 참일 때, 거짓일 때) |
| 리스트 반복 | for, 리스트 컴프리헨션 | rx.foreach(리스트, 함수) |
| 길이 구하기 | len(x) | x.length() |
| 계산·비교 | 파이썬 함수에 Var 넣기 | %, ==, > 같은 Var 연산 |
| 복잡한 계산 | 화면 함수 안의 파이썬 | 이벤트 핸들러에서 계산해 State에 저장 |
알아두기 — 헷갈릴 때는 이렇게 물어보세요. "이 코드는 언제 실행되지?" 화면 함수 안이면 컴파일 타임이라 Var는 아직 빈자리이고, 핸들러 안이면 런타임이라 진짜 값입니다.
format_text를 고쳐서 글자 수가 보이게 해 보세요. 힌트: BadTextState.text.length().count_if_even에서 count가 10 이상이면 "Big!"이 보이게 해 보세요. 힌트: rx.cond(CountEvenState.count >= 10, ...).MyState3처럼 핸들러 안에서 계산하는 방식과 CountEvenState처럼 Var 연산을 쓰는 방식을 비교해 보세요. 어느 쪽이 State 변수가 더 적게 필요한가요?if, for, len()을 State var에 쓸 수 없는 이유를 설명할 수 있다.rx.cond, rx.foreach로 같은 일을 하는 방법을 안다.새 교시·새 강의 소식 받기
이 강의에 새 교시가 더해지거나 이어지는 강의가 열리면 이메일로 알려 드려요.
R
ReflexKR
눌러 보며 배우는 파이썬과 Reflex. 모든 예제는 Reflex 0.10.0에서 직접 실행해 확인했습니다.
ReflexKR은 배너 광고 없이 무료로 운영돼요. 도움이 되셨다면 커피 한 잔으로 응원해 주세요.
© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
질문과 답변
이 교시에서 궁금한 점을 남겨 주세요. 모든 언어 페이지의 질문이 함께 모입니다.