Skip to content

Commit 590a24e

Browse files
committed
Fix double rendering issue on initial page load
1 parent 23c0a77 commit 590a24e

File tree

4 files changed

+83
-7
lines changed

4 files changed

+83
-7
lines changed

src/reactpy_router/routers.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,20 @@ def router(
7474
match = use_memo(lambda: _match_route(resolvers, location, select="first"))
7575

7676
if match:
77-
route_elements = [
78-
_route_state_context(
79-
element,
80-
value=RouteState(set_location, params),
81-
)
82-
for element, params in match
83-
]
77+
# We need skip rendering the application on 'first_load' to avoid
78+
# rendering it twice. The second render occurs following
79+
# the impending on_history_change event
80+
81+
if first_load:
82+
route_elements = []
83+
else:
84+
route_elements = [
85+
_route_state_context(
86+
element,
87+
value=RouteState(set_location, params),
88+
)
89+
for element, params in match
90+
]
8491

8592
def on_history_change(event: dict[str, Any]) -> None:
8693
"""Callback function used within the JavaScript `History` component."""

tests/test_rendering.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import pytest
2+
from reactpy import component, html
3+
from reactpy.testing import DisplayFixture
4+
5+
from reactpy_router import browser_router, route
6+
7+
from .tooling.page import page_stable
8+
9+
10+
@pytest.mark.anyio
11+
async def test_router_simple(display: DisplayFixture):
12+
"""Confirm the number of rendering operations when new pages are first loaded"""
13+
root_render_count = 0
14+
home_page_render_count = 0
15+
not_found_render_count = 0
16+
17+
@component
18+
def root():
19+
nonlocal root_render_count
20+
root_render_count += 1
21+
22+
# https://reactive-python.github.io/reactpy-router/latest/#quick-start
23+
24+
@component
25+
def home_page():
26+
nonlocal home_page_render_count
27+
home_page_render_count += 1
28+
return html.h1("Home Page 🏠")
29+
30+
@component
31+
def not_found():
32+
nonlocal not_found_render_count
33+
not_found_render_count += 1
34+
return html.h1("Missing Link 🔗‍💥")
35+
36+
return browser_router(
37+
route("/", home_page()),
38+
route("{404:any}", not_found()),
39+
)
40+
41+
await display.show(root)
42+
await page_stable(display.page)
43+
44+
assert root_render_count == 1
45+
assert home_page_render_count == 1
46+
assert not_found_render_count == 0
47+
48+
await display.goto("/xxx")
49+
await page_stable(display.page)
50+
51+
assert root_render_count == 2
52+
assert home_page_render_count == 1
53+
assert not_found_render_count == 1
54+
55+
await display.goto("/yyy")
56+
await page_stable(display.page)
57+
58+
assert root_render_count == 3
59+
assert home_page_render_count == 1
60+
assert not_found_render_count == 2
61+
62+
assert True

tests/tooling/__init__.py

Whitespace-only changes.

tests/tooling/page.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from playwright.async_api._generated import Page
2+
3+
4+
async def page_stable(page: Page) -> None:
5+
"""Only return when network is idle and DOM has loaded"""
6+
await page.wait_for_load_state("networkidle")
7+
await page.wait_for_load_state("domcontentloaded")

0 commit comments

Comments
 (0)