reflex icon indicating copy to clipboard operation
reflex copied to clipboard

Changing a Var in Substate A does not trigger computed var in Substate B

Open Lendemor opened this issue 2 years ago β€’ 4 comments
trafficstars

Describe the bug Changing a var in one substate does not trigger computed vars in other substate

To Reproduce Assuming we have the following states:

class State(pc.State):
    my_var: str

class StA(State):
    pass


class StB(State):
    @pc.var
    def comp(self):
        print("called")
        return "res"

and this index method:

def index():
    return pc.center(
        pc.select([1, 2], on_change=StA.set_my_var),
        pc.text(StB.selected_week),
        pc.text(StB.comp),
    )

Comp will not be triggered when you change the value in the select component

Expected behavior Computed var is triggered.

Specifics (please complete the following information):

  • Python Version: 3.8
  • Pynecone Version: 0.1.14

Checklist

  • [ ] Update in parent state should trigger computed vars in substate
  • [ ] Update in a child state should trigger computed vars in siblings states (who have a shared parent state)

Lendemor avatar Feb 03 '23 10:02 Lendemor

Currently the method get_delta() called in process() does not get the computed var of children or siblings state.

Lendemor avatar Feb 15 '23 20:02 Lendemor

@Lendemor we do this for performance reasons - so that we don't have to recompute all the substates every time a var changes. The computed vars are only updated when the substate or its parent updates - not a sibling state.

So currently I think this is the intended design. Is there some use case where this becomes cumbersome / unintuitive? We may need to balance the usability with the performance implications.

picklelo avatar Mar 01 '23 22:03 picklelo

I see.

The usecase where I ran into that problem:

I have a class FilterState(MainState) that is shared between different pages to display different values.

Each page will have something like class Page1State(MainState) that display specific data. If I change a value in FilterState, I want the Page1State computed vars to update to show new values according to those filters.

Based on what you said, I'd have to move all of FilterState into MainState, which is possible but not really nice for compartmentalizing code properly.

Assuming we keep with the current design of not triggering update for sibling state, I believe it would be nice to have a way to mark vars that we want to update on a wider scope.

Maybe as a parameter to the @pc.var decorator that we apply to the computed var ?

The idea would be to have an observer pattern, where we can explicitly tell a computed var to update if the "observed" sibling state has received an update.

Lendemor avatar Mar 02 '23 00:03 Lendemor

That makes a lot of sense. I like the idea of the observer pattern - there's a tradeoff between verbosity and performance that we need to balance.

Would this apply only to computed vars you think? Then maybe we can add an argument for vars that should always be recomputed, even from sibling state changes.

picklelo avatar Mar 02 '23 22:03 picklelo

I plan to fix this in the next week or so as part of #839.

masenf avatar Apr 19 '23 02:04 masenf

This should be fixed from #839

picklelo avatar Jun 15 '23 18:06 picklelo