Skip to content

Commit 96fce16

Browse files
committed
try another approach to fixing switching component def and resetting state
1 parent f0a2766 commit 96fce16

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

src/idom/core/layout.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,19 @@ def _render_model_children(
380380
child,
381381
self._rendering_queue.put,
382382
)
383+
elif old_child_state.is_component_state and (
384+
old_child_state.life_cycle_state.component.definition_id
385+
!= child.definition_id
386+
):
387+
self._unmount_model_states([old_child_state])
388+
old_child_state = None
389+
new_child_state = _make_component_model_state(
390+
new_state,
391+
index,
392+
key,
393+
child,
394+
self._rendering_queue.put,
395+
)
383396
else:
384397
new_child_state = _update_component_model_state(
385398
old_child_state,
@@ -511,10 +524,6 @@ def _update_component_model_state(
511524
life_cycle_state=(
512525
_update_life_cycle_state(old_model_state.life_cycle_state, new_component)
513526
if old_model_state.is_component_state
514-
and (
515-
old_model_state.life_cycle_state.component.definition_id
516-
== new_component.definition_id
517-
)
518527
else _make_life_cycle_state(new_component, schedule_render)
519528
),
520529
)

tests/test_core/test_layout.py

+47-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from idom import html
1212
from idom.config import IDOM_DEBUG_MODE
1313
from idom.core.dispatcher import render_json_patch
14-
from idom.core.hooks import use_effect
14+
from idom.core.hooks import use_effect, use_state
1515
from idom.core.layout import LayoutEvent
1616
from idom.testing import (
1717
HookCatcher,
@@ -877,3 +877,49 @@ def SomeComponent():
877877

878878
assert element_static_handler.target in layout._event_handlers
879879
assert component_static_handler.target not in layout._event_handlers
880+
881+
882+
async def test_switching_component_definition():
883+
toggle_component = idom.Ref()
884+
first_used_state = idom.Ref(None)
885+
second_used_state = idom.Ref(None)
886+
887+
@idom.component
888+
def Root():
889+
toggle, toggle_component.current = use_toggle(True)
890+
if toggle:
891+
return FirstComponent()
892+
else:
893+
return SecondComponent()
894+
895+
@idom.component
896+
def FirstComponent():
897+
first_used_state.current = use_state("first")[0]
898+
# reset state after unmount
899+
use_effect(lambda: lambda: first_used_state.set_current(None))
900+
return html.div()
901+
902+
@idom.component
903+
def SecondComponent():
904+
second_used_state.current = use_state("second")[0]
905+
# reset state after unmount
906+
use_effect(lambda: lambda: second_used_state.set_current(None))
907+
return html.div()
908+
909+
with idom.Layout(Root()) as layout:
910+
await layout.render()
911+
912+
assert first_used_state.current == "first"
913+
assert second_used_state.current is None
914+
915+
toggle_component.current()
916+
await layout.render()
917+
918+
assert first_used_state.current is None
919+
assert second_used_state.current == "second"
920+
921+
toggle_component.current()
922+
await layout.render()
923+
924+
assert first_used_state.current == "first"
925+
assert second_used_state.current is None

0 commit comments

Comments
 (0)