Skip to content

Commit 785d3d2

Browse files
Fix double rendering (#46)
Co-authored-by: Archmonger <[email protected]>
1 parent 23c0a77 commit 785d3d2

File tree

4 files changed

+81
-8
lines changed

4 files changed

+81
-8
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Using the following categories, list your changes in this order:
3434

3535
## [Unreleased]
3636

37-
- Nothing (yet)!
37+
- Fix double rendering issue on initial page load
3838

3939
## [1.0.2] - 2024-10-24
4040

src/reactpy_router/routers.py

+13-7
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,19 @@ 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+
if first_load:
78+
# We need skip rendering the application on 'first_load' to avoid
79+
# rendering it twice. The second render occurs following
80+
# the impending on_history_change event
81+
route_elements = []
82+
else:
83+
route_elements = [
84+
_route_state_context(
85+
element,
86+
value=RouteState(set_location, params),
87+
)
88+
for element, params in match
89+
]
8490

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

tests/test_rendering.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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 .utils import page_load_complete
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+
@component
23+
def home_page():
24+
nonlocal home_page_render_count
25+
home_page_render_count += 1
26+
return html.h1("Home Page 🏠")
27+
28+
@component
29+
def not_found():
30+
nonlocal not_found_render_count
31+
not_found_render_count += 1
32+
return html.h1("Missing Link 🔗‍💥")
33+
34+
return browser_router(
35+
route("/", home_page()),
36+
route("{404:any}", not_found()),
37+
)
38+
39+
await display.show(root)
40+
await page_load_complete(display.page)
41+
42+
assert root_render_count == 1
43+
assert home_page_render_count == 1
44+
assert not_found_render_count == 0
45+
46+
await display.goto("/xxx")
47+
await page_load_complete(display.page)
48+
49+
assert root_render_count == 2
50+
assert home_page_render_count == 1
51+
assert not_found_render_count == 1
52+
53+
await display.goto("/yyy")
54+
await page_load_complete(display.page)
55+
56+
assert root_render_count == 3
57+
assert home_page_render_count == 1
58+
assert not_found_render_count == 2
59+
60+
assert True

tests/utils.py

+7
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_load_complete(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)