Skip to content

[REF-1653] Need to recursively enumerate VarData for all rx.match components #2393

Description

@masenf

When rx.match is used for components that use state or event handlers, the requisite VarData is not getting passed through, resulting in runtime errors when events are triggered.

import reflex as rx


class State(rx.State):
    m: str = "foo"


def index() -> rx.Component:
    return rx.match(
        State.m,
        ("foo", rx.button(State.m, on_click=State.set_m("bar"))),
        ("bar", rx.button(State.m, on_click=State.set_m("foo"))),
        rx.button(State.m),
    )


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

Then click the button and

Unhandled Runtime Error
ReferenceError: addEvents is not defined

Source
pages/index.js (25:48) @ addEvents

  23 |       switch (JSON.stringify(state__state.m)) {
  24 |               case JSON.stringify(`foo`):
> 25 |               return <Button onClick={(_e) => addEvents([Event("state.state.set_m", {value:`bar`})], (_e), {})}>
     |                                              ^
  26 | {state__state.m}
  27 | </Button>;
  28 |               break;

The compiled component looks like

export default function Component() {
  const state__state = useContext(StateContexts.state__state)

  return (
    <Fragment>
  <Fragment_fd0e7cb8f9fb4669a6805377d925fba0/>
  <Fragment>
  {
    (() => {
        switch (JSON.stringify(state__state.m)) {
                case JSON.stringify(`foo`):
                return <Button onClick={(_e) => addEvents([Event("state.state.set_m", {value:`bar`})], (_e), {})}>
  {state__state.m}
</Button>;
                break;
                case JSON.stringify(`bar`):
                return <Button onClick={(_e) => addEvents([Event("state.state.set_m", {value:`foo`})], (_e), {})}>
  {state__state.m}
</Button>;
                break;
            default:
                return <Button>
  {state__state.m}
</Button>;
                break;
        }
    })()
  }
</Fragment>
  <NextHead>
  <title>
  {`Reflex App`}
</title>
  <meta content={`A Reflex app.`} name={`description`}/>
  <meta content={`favicon.ico`} property={`og:image`}/>
</NextHead>
</Fragment>
  )
}

This doesn't get memoized at all, so it actually forces the entire page to depend on the state, which is bad for performance reasons.

rx.match component needs to be a memoization leaf and account for VarData in all components and Vars used by the condition.

From SyncLinear.com | REF-1653

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions