Skip to content

Commit

Permalink
feat: check for key mutation when removing children (#35)
Browse files Browse the repository at this point in the history
  • Loading branch information
iisakkirotko committed Apr 26, 2024
1 parent 1f228b4 commit 16518bf
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 0 deletions.
4 changes: 4 additions & 0 deletions reacton/core.py
Expand Up @@ -230,6 +230,7 @@ def __init__(self, component, args=None, kwargs=None):
self._meta = {}
# for debugging/testing only
self._render_count = 0
self._key_frozen: bool = False

rc = _get_render_context(required=False)
if rc is not None and rc.container_adders:
Expand Down Expand Up @@ -269,6 +270,8 @@ def key(self, value: str):
This can help render performance. See documentation for details.
"""
if self._key_frozen:
raise RuntimeError("Element keys should not be mutated after rendering")
self._key = value
return self

Expand Down Expand Up @@ -1588,6 +1591,7 @@ def _render(self, element: Element, default_key: str, parent_key: str):
key = el._key
if key is None:
key = default_key
el._key_frozen = True

logger.debug("Render: (%s,%s) - %r", parent_key, key, element)

Expand Down
22 changes: 22 additions & 0 deletions reacton/core_test.py
Expand Up @@ -3186,3 +3186,25 @@ def Test():
assert vbox.children[0].description == "1"
assert vbox.children[1].description == "2"
rc.close()


def test_key_mutate_protection(Container):
button = ButtonComponentFunction(description="Hi")
set_state = lambda value: None # noqa

@react.component
def Test():
nonlocal set_state
state, set_state = react.use_state(0)
if state == 0:
return Container(children=[button])
else:
return Container(children=[button.key("i_should_not_be_mutated")]).key("bla")

box, rc = react.render(Test(), handle_error=False)
assert rc.find(widgets.Button).widget.description == "Hi"
assert button._key is None
with pytest.raises(RuntimeError, match="Element keys should not be mutated after rendering"):
set_state(1)
rc.render(w.HTML(value="recover").key("HTML"))
rc.close()

0 comments on commit 16518bf

Please sign in to comment.