Skip to content

[REF-1035] ComputedVar in substate is not recomputed #2066

@masenf

Description

@masenf

Describe the bug
A ComputedVar should be recomputed everytime the state is touched, even if there are no changes. This only occurs for the base State, not for substates.

To Reproduce

import time

import reflex as rx


class State(rx.State):
    @rx.var
    def last_update(self) -> str:
        return time.strftime("%H:%M:%S")


class SubState(State):
    ss_count: int = 0

    @rx.var
    def last_update2(self) -> str:
        return time.strftime("%H:%M:%S")

    def no_op(self):
        print("no_op")

    def increment(self):
        self.ss_count += 1


def index() -> rx.Component:
    return rx.vstack(
        rx.heading(State.last_update),
        rx.heading(SubState.last_update2),
        rx.button("No-op", on_click=SubState.no_op),
        rx.button(f"SS Count {SubState.ss_count}", on_click=SubState.increment),
    )


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

Expected behavior
Clicking either button should update the timestamp in both states, since they are both @rx.var.

However, SubState.last_update2 only gets recomputed when some other var in the substate changes.

Specifics (please complete the following information):

  • Python Version: 3.11.6
  • Reflex Version: 0.3.1
  • OS: macOS 14

Additional context
The problem seems to be here

reflex/reflex/state.py

Lines 1123 to 1124 in 2693340

for substate in self.dirty_substates:
delta.update(substates[substate].get_delta())

State.get_delta is only recursing into substates which have been marked dirty, and if the substate does not have any other changes, then the ComputedVar itself would not be sufficient to have the substate marked dirty.

#2067

From SyncLinear.com | REF-1035

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