Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
masenf opened this issue Oct 28, 2023 · 0 comments · Fixed by #2067
Closed

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

masenf opened this issue Oct 28, 2023 · 0 comments · Fixed by #2067
Assignees

Comments

@masenf
Copy link
Collaborator

masenf commented Oct 28, 2023

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

@masenf masenf changed the title ComputedVar is substate is not recomputed [REF-1035] ComputedVar is substate is not recomputed Oct 28, 2023
@masenf masenf changed the title [REF-1035] ComputedVar is substate is not recomputed [REF-1035] ComputedVar in substate is not recomputed Oct 28, 2023
masenf added a commit that referenced this issue Oct 28, 2023
…ates

Instead of calculating these every time there is a delta, determine them
at subclass definition time (or when adding a var dynamically).

This should improve performance for every delta calculation.

It also fixes #2066 by tracking substates which have ComputedVar with
_cache=False

Fix REF-1035
@masenf masenf self-assigned this Nov 2, 2023
@masenf masenf modified the milestones: v.6, v.7 Nov 2, 2023
@masenf masenf modified the milestones: v.7, v.9 Nov 19, 2023
masenf added a commit that referenced this issue Nov 22, 2023
…ates

Instead of calculating these every time there is a delta, determine them
at subclass definition time (or when adding a var dynamically).

This should improve performance for every delta calculation.

It also fixes #2066 by tracking substates which have ComputedVar with
_cache=False

Fix REF-1035
@masenf masenf modified the milestones: v.9, v.10 Nov 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant