Skip to content

Commit 161e788

Browse files
committed
skip rendering none
1 parent 43009e4 commit 161e788

File tree

3 files changed

+29
-25
lines changed

3 files changed

+29
-25
lines changed

Diff for: src/py/reactpy/reactpy/core/layout.py

+8-7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
EventHandlerDict,
4040
LayoutEventMessage,
4141
LayoutUpdateMessage,
42+
VdomChild,
4243
VdomDict,
4344
VdomJson,
4445
)
@@ -189,9 +190,7 @@ async def _render_component(
189190
# wrap the model in a fragment (i.e. tagName="") to ensure components have
190191
# a separate node in the model state tree. This could be removed if this
191192
# components are given a node in the tree some other way
192-
wrapper_model: VdomDict = {"tagName": ""}
193-
if raw_model is not None:
194-
wrapper_model["children"] = [raw_model]
193+
wrapper_model: VdomDict = {"tagName": "", "children": [raw_model]}
195194
await self._render_model(exit_stack, old_state, new_state, wrapper_model)
196195
except Exception as error:
197196
logger.exception(f"Failed to render {component}")
@@ -332,7 +331,7 @@ async def _render_model_children(
332331
child_type_key_tuples = list(_process_child_type_and_key(raw_children))
333332

334333
new_keys = {item[2] for item in child_type_key_tuples}
335-
if len(new_keys) != len(raw_children):
334+
if len(new_keys) != len(child_type_key_tuples):
336335
key_counter = Counter(item[2] for item in child_type_key_tuples)
337336
duplicate_keys = [key for key, count in key_counter.items() if count > 1]
338337
msg = f"Duplicate keys {duplicate_keys} at {new_state.patch_path or '/'!r}"
@@ -423,7 +422,7 @@ async def _render_model_children_without_old_state(
423422
child_type_key_tuples = list(_process_child_type_and_key(raw_children))
424423

425424
new_keys = {item[2] for item in child_type_key_tuples}
426-
if len(new_keys) != len(raw_children):
425+
if len(new_keys) != len(child_type_key_tuples):
427426
key_counter = Counter(item[2] for item in child_type_key_tuples)
428427
duplicate_keys = [key for key, count in key_counter.items() if count > 1]
429428
msg = f"Duplicate keys {duplicate_keys} at {new_state.patch_path or '/'!r}"
@@ -721,10 +720,12 @@ async def get(self) -> _Type:
721720

722721

723722
def _process_child_type_and_key(
724-
children: list[Any],
723+
children: list[VdomChild],
725724
) -> Iterator[tuple[Any, _ElementType, Any]]:
726725
for index, child in enumerate(children):
727-
if isinstance(child, dict):
726+
if child is None:
727+
continue
728+
elif isinstance(child, dict):
728729
child_type = _DICT_TYPE
729730
key = child.get("key")
730731
elif isinstance(child, ComponentType):

Diff for: src/py/reactpy/reactpy/core/types.py

+2-9
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ async def __aexit__(
9191
VdomAttributes = Mapping[str, Any]
9292
"""Describes the attributes of a :class:`VdomDict`"""
9393

94-
VdomChild: TypeAlias = "ComponentType | VdomDict | str"
94+
VdomChild: TypeAlias = "ComponentType | VdomDict | str | None | Any"
9595
"""A single child element of a :class:`VdomDict`"""
9696

9797
VdomChildren: TypeAlias = "Sequence[VdomChild] | VdomChild"
@@ -100,14 +100,7 @@ async def __aexit__(
100100

101101
class _VdomDictOptional(TypedDict, total=False):
102102
key: Key | None
103-
children: Sequence[
104-
# recursive types are not allowed yet:
105-
# https://github.com/python/mypy/issues/731
106-
ComponentType
107-
| dict[str, Any]
108-
| str
109-
| Any
110-
]
103+
children: Sequence[ComponentType | VdomChild]
111104
attributes: VdomAttributes
112105
eventHandlers: EventHandlerDict
113106
importSource: ImportSourceDict

Diff for: src/py/reactpy/tests/test_core/test_layout.py

+19-9
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,6 @@ def SimpleComponent():
102102
)
103103

104104

105-
async def test_component_can_return_none():
106-
@reactpy.component
107-
def SomeComponent():
108-
return None
109-
110-
async with reactpy.Layout(SomeComponent()) as layout:
111-
assert (await layout.render())["model"] == {"tagName": ""}
112-
113-
114105
async def test_nested_component_layout():
115106
parent_set_state = reactpy.Ref(None)
116107
child_set_state = reactpy.Ref(None)
@@ -1310,3 +1301,22 @@ def child_2():
13101301

13111302
assert child_1_render_count.current == 1
13121303
assert child_2_render_count.current == 1
1304+
1305+
1306+
async def test_none_does_not_render():
1307+
@component
1308+
def Root():
1309+
return html.div(None, Child())
1310+
1311+
@component
1312+
def Child():
1313+
return None
1314+
1315+
async with layout_runner(Layout(Root())) as runner:
1316+
tree = await runner.render()
1317+
assert tree == {
1318+
"tagName": "",
1319+
"children": [
1320+
{"tagName": "div", "children": [{"tagName": "", "children": []}]}
1321+
],
1322+
}

0 commit comments

Comments
 (0)