reflex icon indicating copy to clipboard operation
reflex copied to clipboard

State variable update doesn't trigger update in frontend

Open bamchip opened this issue 2 years ago β€’ 1 comments

Describe the bug

  • When I update an attribute of a pc.Model in an event handler (see Topic's is_selected below) this doesn't trigger an update in the frontend as it should. Only way to get the update to occur in the frontend is to add self.topics = self.topics at the end of toggle_topic_selected which seems a bit hacky.

To Reproduce Steps to reproduce the behavior:

  • Code/Link to Repo:
###### model code ######

class Topic(pc.Model):
    name: str
    is_selected: bool = False

###### state code ######

class TopicsState(BaseState):
    """The topics state."""

    topics: List[Topic] = []

    def refresh_user_topics(self):
        # logic here to set self.topics        

    def toggle_topic_selected(self, topic_idx: int) -> None:
        print(f"IDX: {topic_idx}; Is Selected: {self.topics[topic_idx].is_selected}")
        topic = self.topics[topic_idx]
        topic.is_selected = not topic.is_selected
        print(f" Is Selected: {self.topics[topic_idx].is_selected}")


###### page code ######

def to_ui_topic(topic: TopicsState, idx: int):
    selected_background_color = "#b8b8b8"
    not_selected_background_color = "#fff"
    print("here")
    return pc.box(
        pc.vstack(
            pc.text(topic.name),
            spacing="0.3rem",
            align_items="center",
        ),
        background_color=pc.cond(topic.is_selected, selected_background_color, not_selected_background_color),
        padding="1rem",
        border_radius="30px",
        border="1px solid #ddd",        
        on_click=TopicsState.toggle_topic_selected(idx),
    )


pc.vstack(
    pc.foreach(TopicsState.topics, lambda topic, idx: to_ui_topic(topic, idx)),
    margin_top="2rem",
    spacing="1rem",
    align_items="left",
),

Expected behavior

  • Any update to a state var should be available and reflect in the frontend as is described in the documentation.

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

** Specifics (please complete the following information):**

  • Python Version:
  • Reflex Version:
  • OS:
  • Browser (Optional):

Additional context Add any other context about the problem here.

  • I've anecdotally noticed this behavior inside other pc.cond statements in the frontend with even booleans.

bamchip avatar Jun 29 '23 21:06 bamchip

This is currently a limitation with how change detection is implemented on list items. Essentially, the state engine doesn't know that topic is associated with a particular index in the list. When the attributes of the item are modified, there's nothing that notifies the state to mark the containing list as dirty.

masenf avatar Jun 30 '23 21:06 masenf

Should be fixed in reflex 0.2.8+ via https://github.com/reflex-dev/reflex/pull/1748

masenf avatar Nov 27 '23 22:11 masenf