Skip to content

Keep only the last rerender reasons, two by default - #60

Merged
maartenbreddels merged 1 commit into
masterfrom
fix/rerender-reasons-leak
Sep 28, 2026
Merged

maartenbreddels merged 1 commit into
masterfrom
fix/rerender-reasons-leak

Conversation

@maartenbreddels

Copy link
Copy Markdown
Contributor

Why

Every state change adds a RerenderReason(prev_value, next_value) to rc._rerender_needed_reasons, and nothing ever removes it. So a long-lived page keeps every old state value alive (dataframes, big lists, ...) until the page closes. This happens in both renderers, and in production today.

Only the "Too many renders" error message reads this list, and it showed just the last two reasons.

What

  • The list is now a deque(maxlen=2), so the memory stays bounded.
  • REACTON_RERENDER_REASONS=N keeps more reasons when you debug a render loop. The error message now shows all the reasons it keeps, not only the last two.

Tests

  • test_state_changes_do_not_keep_old_values_alive: does 20 state sets and checks that only a few old values stay alive. It fails without the fix, in both renderers.
  • test_debug_infinite_loop checks the message and the render count now, not the length of the list.
  • test_debug_infinite_loop_more_reasons: the env var gives more reasons in the message.
  • Solara's unit suite gives the same results as with 1.10.3, with REACTON_FAST=0 and =1.

🤖 Generated with Claude Code

Every state change appended a RerenderReason with the previous and the
next state value to the render context, and nothing ever removed them.
A long-lived page therefore kept every old state value alive until the
page was closed: 1000 state sets kept 1000 old values (a dataframe,
a big list, ...) in memory, in both renderers.

The reasons are only read for the "too many renders" error message,
which showed the last two. A deque with maxlen=2 keeps that message and
bounds the memory. REACTON_RERENDER_REASONS keeps more of them when
debugging a render loop, and the message now shows all that are kept.

test_debug_infinite_loop checked the length of the list to see that the
loop ran; it now checks the error message and the render count instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@maartenbreddels
maartenbreddels merged commit 2bc84e0 into master Sep 28, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant