Skip to content

Commit 0ad0a84

Browse files
authored
fix recursive UI (#4599)
* fix recursive UI * get it right pyright * dang it darglint
1 parent 880975a commit 0ad0a84

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

reflex/components/base/bare.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,14 @@ def _render(self) -> Tag:
108108
return Tagless(contents=f"{{{self.contents!s}}}")
109109
return Tagless(contents=str(self.contents))
110110

111-
def _get_vars(self, include_children: bool = False) -> Iterator[Var]:
111+
def _get_vars(
112+
self, include_children: bool = False, ignore_ids: set[int] | None = None
113+
) -> Iterator[Var]:
112114
"""Walk all Vars used in this component.
113115
114116
Args:
115117
include_children: Whether to include Vars from children.
118+
ignore_ids: The ids to ignore.
116119
117120
Yields:
118121
The contents if it is a Var, otherwise nothing.

reflex/components/component.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,18 +1020,22 @@ def _get_vars_from_event_triggers(
10201020
event_args.append(spec)
10211021
yield event_trigger, event_args
10221022

1023-
def _get_vars(self, include_children: bool = False) -> list[Var]:
1023+
def _get_vars(
1024+
self, include_children: bool = False, ignore_ids: set[int] | None = None
1025+
) -> Iterator[Var]:
10241026
"""Walk all Vars used in this component.
10251027
10261028
Args:
10271029
include_children: Whether to include Vars from children.
1030+
ignore_ids: The ids to ignore.
10281031
1029-
Returns:
1032+
Yields:
10301033
Each var referenced by the component (props, styles, event handlers).
10311034
"""
1032-
vars = getattr(self, "__vars", None)
1035+
ignore_ids = ignore_ids or set()
1036+
vars: List[Var] | None = getattr(self, "__vars", None)
10331037
if vars is not None:
1034-
return vars
1038+
yield from vars
10351039
vars = self.__vars = []
10361040
# Get Vars associated with event trigger arguments.
10371041
for _, event_vars in self._get_vars_from_event_triggers(self.event_triggers):
@@ -1075,12 +1079,15 @@ def _get_vars(self, include_children: bool = False) -> list[Var]:
10751079
# Get Vars associated with children.
10761080
if include_children:
10771081
for child in self.children:
1078-
if not isinstance(child, Component):
1082+
if not isinstance(child, Component) or id(child) in ignore_ids:
10791083
continue
1080-
child_vars = child._get_vars(include_children=include_children)
1084+
ignore_ids.add(id(child))
1085+
child_vars = child._get_vars(
1086+
include_children=include_children, ignore_ids=ignore_ids
1087+
)
10811088
vars.extend(child_vars)
10821089

1083-
return vars
1090+
yield from vars
10841091

10851092
def _event_trigger_values_use_state(self) -> bool:
10861093
"""Check if the values of a component's event trigger use state.
@@ -1811,19 +1818,25 @@ def get_prop_vars(self) -> List[Var]:
18111818
for name, prop in self.props.items()
18121819
]
18131820

1814-
def _get_vars(self, include_children: bool = False) -> list[Var]:
1821+
def _get_vars(
1822+
self, include_children: bool = False, ignore_ids: set[int] | None = None
1823+
) -> Iterator[Var]:
18151824
"""Walk all Vars used in this component.
18161825
18171826
Args:
18181827
include_children: Whether to include Vars from children.
1828+
ignore_ids: The ids to ignore.
18191829
1820-
Returns:
1830+
Yields:
18211831
Each var referenced by the component (props, styles, event handlers).
18221832
"""
1823-
return (
1824-
super()._get_vars(include_children=include_children)
1825-
+ [prop for prop in self.props.values() if isinstance(prop, Var)]
1826-
+ self.get_component(self)._get_vars(include_children=include_children)
1833+
ignore_ids = ignore_ids or set()
1834+
yield from super()._get_vars(
1835+
include_children=include_children, ignore_ids=ignore_ids
1836+
)
1837+
yield from filter(lambda prop: isinstance(prop, Var), self.props.values())
1838+
yield from self.get_component(self)._get_vars(
1839+
include_children=include_children, ignore_ids=ignore_ids
18271840
)
18281841

18291842
@lru_cache(maxsize=None) # noqa

reflex/components/el/elements/forms.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,12 @@ def _get_form_refs(self) -> Dict[str, Any]:
250250
)
251251
return form_refs
252252

253-
def _get_vars(self, include_children: bool = True) -> Iterator[Var]:
254-
yield from super()._get_vars(include_children=include_children)
253+
def _get_vars(
254+
self, include_children: bool = True, ignore_ids: set[int] | None = None
255+
) -> Iterator[Var]:
256+
yield from super()._get_vars(
257+
include_children=include_children, ignore_ids=ignore_ids
258+
)
255259
yield from self._get_form_refs().values()
256260

257261
def _exclude_props(self) -> list[str]:

0 commit comments

Comments
 (0)