reflex icon indicating copy to clipboard operation
reflex copied to clipboard

event handlers are missing when components mutably statefull-ized

Open tim-haselhoff opened this issue 5 months ago β€’ 4 comments

Describe the bug A clear and concise description of what the bug is.

When wrapping a button within a tooltip that is within a rx.cond it causes an on_click is not defined error while without the rx.cond it works perfectly fine.

To Reproduce Steps to reproduce the behavior:

  1. Create a reflex application with the code
  2. Run it and open the browser
  • Code/Link to Repo:
import reflex as rx

class State(rx.State):
    @rx.event
    def on_click_handler(self) -> None:
        print("Button clicked! :)")

def index() -> rx.Component:
    content = "Hello world!"
    button = rx.el.button(content, on_click=State.on_click_handler)
    wrapped = rx.el.span(button)
    tooltip = rx.Var.create("This is a tooltip")
    return rx.container(
        # This breaks
        rx.cond(
            tooltip,
            rx.tooltip(wrapped, content=tooltip),
            button,
        ),
        # Without rx.cond it works
        rx.tooltip(wrapped, content=tooltip)
    )


app = rx.App()
app.add_page(index)

Expected behavior It doesnt give an error

Screenshots If applicable, add screenshots to help explain your problem.

Image Image

Specifics (please complete the following information):

  • Python Version: 3.13
  • Reflex Version: 0.8.1
  • OS: linux
  • Browser (Optional): Chrome

Additional context Add any other context about the problem here.

tim-haselhoff avatar Jul 13 '25 17:07 tim-haselhoff

This is a context issue because the defined event has been split by the rx.cond

Use rx.memo to decorate the function using the tooltip and cond, and it should go away

Lendemor avatar Jul 13 '25 18:07 Lendemor

simpler repro:

import reflex as rx


class State(rx.State):
    @rx.event
    def on_click_handler(self) -> None:
        print("Button clicked! :)")


def index() -> rx.Component:
    button = rx.el.button("Hello world!", on_click=State.on_click_handler)
    return rx.container(
        rx.cond(
            True,
            button,
        ),
        rx.box(rx.el.span(button)),
    )


app = rx.App()
app.add_page(index)

adhami3310 avatar Jul 14 '25 21:07 adhami3310

workaround (not using the same object, getting a different one):

import reflex as rx


class State(rx.State):
    @rx.event
    def on_click_handler(self) -> None:
        print("Button clicked! :)")


def button():
    return rx.el.button("Hello world!", on_click=State.on_click_handler)


def wrapped():
    return rx.el.span(button())


def index() -> rx.Component:
    tooltip = rx.Var.create("This is a tooltip")
    return rx.container(
        # This breaks
        rx.cond(
            tooltip,
            rx.tooltip(wrapped(), content=tooltip),
            button(),
        ),
        # Without rx.cond it works
        rx.tooltip(wrapped(), content=tooltip),
    )


app = rx.App()
app.add_page(index)

adhami3310 avatar Jul 14 '25 21:07 adhami3310