Add use_session_state hook for persistent state across WebSocket reconnects - #300
Merged
Merged
Conversation
Archmonger
marked this pull request as ready for review
September 14, 2026 23:57
added 3 commits
September 15, 2026 00:48
Add validation for the new REACTPY_SESSION_STATE_* and REACTPY_CLEAN_SESSION_STATE settings introduced for the use_session_state hook.
Add reference docs for the new REACTPY_SESSION_STATE_* and REACTPY_CLEAN_SESSION_STATE settings, and document the use_session_state hook with an example.
Add 'debounced' and 'picklable' to the docs dictionary, and reword the 'un-picklable' phrase in the use_session_state docs so the docs build passes in strict spellcheck mode.
Closed
1 task
…c sync Change the default REACTPY_SESSION_STATE_SYNC_INTERVAL from 5 to 10 seconds, and allow setting it to 0 to disable periodic syncing. When 0, state is only persisted to the database on unmount (e.g. when a WebSocket reconnects). Update the docs, changelog, and system check hints accordingly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Add a dedicated, database-backed hook
reactpy_django.hooks.use_session_state(default, key)that persists state so it survives WebSocket reconnects (and, optionally, page reloads).Problem
On a WebSocket reconnect the client re-sends
mount-component, the server creates a freshLayout, and all in-memory component state (use_state, etc.) is lost. This is especially problematic for deployments that use multiple processes orreactpy-django's built-in round-robin load balancing across hosts, where a reconnect may land on a different worker whose memory does not contain the previous state.Solution
Add a database-backed hook so state is durable across process restarts and round-robin hosts, unlike an in-memory approach.
Design decisions
REACTPY_SESSION_STATE_MODE:"tab"(default): scoped to the rendered component's UUID (a per-tab/per-component token that is stable across reconnects). Works for anonymous users withoutdjango.contrib.sessionsand isolates state between browser tabs."user": scoped to the authenticated user's PK, falling back to a per-tab token for anonymous users.REACTPY_SESSION_STATE_SYNC_INTERVAL, default 10s) so rapid state changes (e.g. typing) are coalesced into one DB write; state is also flushed on unmount so the latest value is persisted before a reconnect.dill(already a dependency) to support arbitrary serializable Python objects.Settings added
REACTPY_SESSION_STATE_MODE"tab"REACTPY_SESSION_STATE_SYNC_INTERVAL10REACTPY_SESSION_STATE_MAX_AGE259200(3 days)REACTPY_CLEAN_SESSION_STATETrueNotes for reviewers
{% reactpy %}template tag. This is stable across reconnects (baked into the rendered HTML) but not across full page reloads. A future enhancement could lift the per-tab token into ReactPy core for a more stable, browser-persistent identity.Checklist
Please update this checklist as you complete each item:
By submitting this pull request I agree that all contributions comply with this project's open source license(s).