component.get_hooks: inject hook code into component func (#810)
This commit is contained in:
parent
3e2ebd9dea
commit
c3148d348c
@ -70,6 +70,7 @@ def _compile_page(component: Component, state: Type[State]) -> str:
|
|||||||
state=utils.compile_state(state),
|
state=utils.compile_state(state),
|
||||||
events=utils.compile_events(state),
|
events=utils.compile_events(state),
|
||||||
effects=utils.compile_effects(state),
|
effects=utils.compile_effects(state),
|
||||||
|
hooks=path_ops.join(component.get_hooks()),
|
||||||
render=component.render(),
|
render=component.render(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ PAGE = path_ops.join(
|
|||||||
"{state}",
|
"{state}",
|
||||||
"{events}",
|
"{events}",
|
||||||
"{effects}",
|
"{effects}",
|
||||||
|
"{hooks}",
|
||||||
"return (",
|
"return (",
|
||||||
"{render}",
|
"{render}",
|
||||||
")",
|
")",
|
||||||
|
@ -459,6 +459,29 @@ class Component(Base, ABC):
|
|||||||
self._get_imports(), *[child.get_imports() for child in self.children]
|
self._get_imports(), *[child.get_imports() for child in self.children]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _get_hooks(self) -> Optional[str]:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_hooks(self) -> Set[str]:
|
||||||
|
"""Get javascript code for react hooks.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The code that should appear just before returning the rendered component.
|
||||||
|
"""
|
||||||
|
# Store the code in a set to avoid duplicates.
|
||||||
|
code = set()
|
||||||
|
|
||||||
|
# Add the hook code for this component.
|
||||||
|
hooks = self._get_hooks()
|
||||||
|
if hooks is not None:
|
||||||
|
code.add(hooks)
|
||||||
|
|
||||||
|
# Add the hook code for the children.
|
||||||
|
for child in self.children:
|
||||||
|
code.update(child.get_hooks())
|
||||||
|
|
||||||
|
return code
|
||||||
|
|
||||||
def get_custom_components(
|
def get_custom_components(
|
||||||
self, seen: Optional[Set[str]] = None
|
self, seen: Optional[Set[str]] = None
|
||||||
) -> Set[CustomComponent]:
|
) -> Set[CustomComponent]:
|
||||||
|
@ -83,6 +83,36 @@ def component2() -> Type[Component]:
|
|||||||
return TestComponent2
|
return TestComponent2
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def component3() -> Type[Component]:
|
||||||
|
"""A test component with hook defined.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A test component.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class TestComponent3(Component):
|
||||||
|
def _get_hooks(self) -> str:
|
||||||
|
return "const a = () => true"
|
||||||
|
|
||||||
|
return TestComponent3
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def component4() -> Type[Component]:
|
||||||
|
"""A test component with hook defined.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A test component.
|
||||||
|
"""
|
||||||
|
|
||||||
|
class TestComponent4(Component):
|
||||||
|
def _get_hooks(self) -> str:
|
||||||
|
return "const b = () => false"
|
||||||
|
|
||||||
|
return TestComponent4
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def on_click1() -> EventHandler:
|
def on_click1() -> EventHandler:
|
||||||
"""A sample on click function.
|
"""A sample on click function.
|
||||||
@ -363,3 +393,42 @@ def test_invalid_event_handler_args(component2, TestState):
|
|||||||
component2.create(on_open=TestState.do_something)
|
component2.create(on_open=TestState.do_something)
|
||||||
with pytest.raises(ValueError):
|
with pytest.raises(ValueError):
|
||||||
component2.create(on_open=[TestState.do_something_arg, TestState.do_something])
|
component2.create(on_open=[TestState.do_something_arg, TestState.do_something])
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_hooks_nested(component1, component2, component3):
|
||||||
|
"""Test that a component returns hooks from child components.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
component1: test component.
|
||||||
|
component2: another component.
|
||||||
|
component3: component with hooks defined.
|
||||||
|
"""
|
||||||
|
c = component1.create(
|
||||||
|
component2.create(arr=[]),
|
||||||
|
component3.create(),
|
||||||
|
component3.create(),
|
||||||
|
component3.create(),
|
||||||
|
text="a",
|
||||||
|
number=1,
|
||||||
|
)
|
||||||
|
assert c.get_hooks() == component3().get_hooks()
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_hooks_nested2(component3, component4):
|
||||||
|
"""Test that a component returns both when parent and child have hooks.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
component3: component with hooks defined.
|
||||||
|
component4: component with different hooks defined.
|
||||||
|
"""
|
||||||
|
exp_hooks = component3().get_hooks().union(component4().get_hooks())
|
||||||
|
assert component3.create(component4.create()).get_hooks() == exp_hooks
|
||||||
|
assert component4.create(component3.create()).get_hooks() == exp_hooks
|
||||||
|
assert (
|
||||||
|
component4.create(
|
||||||
|
component3.create(),
|
||||||
|
component4.create(),
|
||||||
|
component3.create(),
|
||||||
|
).get_hooks()
|
||||||
|
== exp_hooks
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user