fix hook order to use ref inside user hooks (#2906)

* fix hook order to use ref inside user hooks

* 2nd attempt to fix ref_hook order

* add missing definition

* remove print statements
This commit is contained in:
Thomas Brandého 2024-03-27 12:49:11 +01:00 committed by GitHub
parent 012151132e
commit 94823f1317
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 48 additions and 12 deletions

View File

@ -8,6 +8,10 @@
{% block export %} {% block export %}
export default function Component() { export default function Component() {
{% for ref_hook in ref_hooks %}
{{ ref_hook }}
{% endfor %}
{% for hook in hooks %} {% for hook in hooks %}
{{ hook }} {{ hook }}
{% endfor %} {% endfor %}

View File

@ -1,6 +1,10 @@
{% import 'web/pages/utils.js.jinja2' as utils %} {% import 'web/pages/utils.js.jinja2' as utils %}
export function {{tag_name}} () { export function {{tag_name}} () {
{% for ref_hook in component.get_ref_hooks() %}
{{ ref_hook }}
{% endfor %}
{% for hook in component.get_hooks_internal() %} {% for hook in component.get_hooks_internal() %}
{{ hook }} {{ hook }}
{% endfor %} {% endfor %}

View File

@ -119,6 +119,7 @@ def _compile_page(
imports=imports, imports=imports,
dynamic_imports=component.get_dynamic_imports(), dynamic_imports=component.get_dynamic_imports(),
custom_codes=component.get_custom_code(), custom_codes=component.get_custom_code(),
ref_hooks=component.get_ref_hooks(),
hooks=component.get_hooks_internal() | component.get_hooks(), hooks=component.get_hooks_internal() | component.get_hooks(),
render=component.render(), render=component.render(),
**kwargs, **kwargs,

View File

@ -74,6 +74,14 @@ class BaseComponent(Base, ABC):
The dictionary for template of the component. The dictionary for template of the component.
""" """
@abstractmethod
def get_ref_hooks(self) -> set[str]:
"""Get the hooks required by refs in this component.
Returns:
The hooks for the refs.
"""
@abstractmethod @abstractmethod
def get_hooks_internal(self) -> set[str]: def get_hooks_internal(self) -> set[str]:
"""Get the reflex internal hooks for the component and its children. """Get the reflex internal hooks for the component and its children.
@ -636,9 +644,11 @@ class Component(BaseComponent, ABC):
) )
children = [ children = [
child (
if isinstance(child, Component) child
else Bare.create(contents=Var.create(child, _var_is_string=True)) if isinstance(child, Component)
else Bare.create(contents=Var.create(child, _var_is_string=True))
)
for child in children for child in children
] ]
@ -1130,14 +1140,10 @@ class Component(BaseComponent, ABC):
Set of internally managed hooks. Set of internally managed hooks.
""" """
return ( return (
set( self._get_vars_hooks()
hook
for hook in [self._get_mount_lifecycle_hook(), self._get_ref_hook()]
if hook
)
| self._get_vars_hooks()
| self._get_events_hooks() | self._get_events_hooks()
| self._get_special_hooks() | self._get_special_hooks()
| set(hook for hook in [self._get_mount_lifecycle_hook()] if hook)
) )
def _get_hooks(self) -> str | None: def _get_hooks(self) -> str | None:
@ -1150,6 +1156,19 @@ class Component(BaseComponent, ABC):
""" """
return return
def get_ref_hooks(self) -> Set[str]:
"""Get the ref hooks for the component and its children.
Returns:
The ref hooks.
"""
ref_hook = self._get_ref_hook()
hooks = set() if ref_hook is None else {ref_hook}
for child in self.children:
hooks |= child.get_ref_hooks()
return hooks
def get_hooks_internal(self) -> set[str]: def get_hooks_internal(self) -> set[str]:
"""Get the reflex internal hooks for the component and its children. """Get the reflex internal hooks for the component and its children.
@ -1424,9 +1443,9 @@ class CustomComponent(Component):
return [ return [
BaseVar( BaseVar(
_var_name=name, _var_name=name,
_var_type=prop._var_type _var_type=(
if types._isinstance(prop, Var) prop._var_type if types._isinstance(prop, Var) else type(prop)
else type(prop), ),
) )
for name, prop in self.props.items() for name, prop in self.props.items()
] ]
@ -1808,6 +1827,14 @@ class StatefulComponent(BaseComponent):
) )
return trigger_memo return trigger_memo
def get_ref_hooks(self) -> set[str]:
"""Get the ref hooks for the component and its children.
Returns:
The ref hooks.
"""
return set()
def get_hooks_internal(self) -> set[str]: def get_hooks_internal(self) -> set[str]:
"""Get the reflex internal hooks for the component and its children. """Get the reflex internal hooks for the component and its children.