Skip to content

Commit

Permalink
fix: get_widget did not always work for function components
Browse files Browse the repository at this point in the history
We only searched through the current context, which made it work
when all parents are widget components (which do not create a new
context).
Now we search through all child contexts, which makes it work for
function components as well.

Fixes #14
  • Loading branch information
maartenbreddels committed Oct 3, 2023
1 parent 8e0db3e commit dfdca66
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 20 deletions.
33 changes: 16 additions & 17 deletions reacton/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -742,23 +742,22 @@ def get_widget(el: Element):
element will be returned.
"""
rc = get_render_context()
if rc.context is None:
raise RuntimeError("get_widget() can only be used in use_effect")
if el.is_shared:
if el not in rc._shared_widgets:
if id(el) in rc._old_element_ids:
raise KeyError(f"Element {el} was found to be in a previous render, you may have used a stale element")
else:
raise KeyError(f"Element {el} not found in all known widgets for the component {rc._shared_widgets}")
return rc._shared_widgets[el]
else:

if el not in rc.context.element_to_widget:
if id(el) in rc._old_element_ids:
raise KeyError(f"Element {el} was found to be in a previous render, you may have used a stale element")
else:
raise KeyError(f"Element {el} not found in all known widgets for the component {rc.context.widgets}")
return rc.context.element_to_widget[el]
# breadth first search
contexts = [rc.context]
while contexts:
context = contexts.pop()
if context is None:
raise RuntimeError("get_widget() can only be used in use_effect")
contexts.extend(context.children.values())
if el.is_shared:
if el not in rc._shared_widgets:
return rc._shared_widgets[el]
else:
if el in context.element_to_widget:
return context.element_to_widget[el]
if id(el) in rc._old_element_ids:
raise KeyError(f"Element {el} was found to be in a previous render, you may have used a stale element")
raise KeyError(f"Element {el} not found in all known widgets") # for the component {context.widgets}")


def use_state(initial: T, key: str = None, eq: Callable[[Any, Any], bool] = None) -> Tuple[T, Callable[[Union[T, Callable[[T], T]]], None]]:
Expand Down
6 changes: 3 additions & 3 deletions reacton/core_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1380,7 +1380,7 @@ def ContainerContext(exponent=1.2):
rc.close()


def test_get_widget():
def test_get_widget(Container):

button1 = None
button2 = None
Expand All @@ -1394,12 +1394,12 @@ def get_widgets():
button2 = react.core.get_widget(button2el)

use_effect(get_widgets)
with w.VBox() as main:
with Container() as main:
button1el = w.Button(description="1")
button2el = w.Button(description="2")
return main

box, rc = react.render_fixed(Multiple())
box, rc = react.render_fixed(Multiple(), handle_error=False)
assert box.children[0] is button1
assert box.children[1] is button2
rc.close()
Expand Down

0 comments on commit dfdca66

Please sign in to comment.