Fix Fast Refresh state loss when editing files that call constate(...)#179
Closed
diegohaz wants to merge 1 commit into
Closed
Fix Fast Refresh state loss when editing files that call constate(...)#179diegohaz wants to merge 1 commit into
constate(...)#179diegohaz wants to merge 1 commit into
Conversation
In dev, cache the Provider and hooks returned by `constate(...)` so HMR re-evaluation of the caller's module reuses the same component identities instead of remounting and losing state. Closes #146. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
commit: |
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.
Summary
process.env.NODE_ENV !== "production"),constate(useValue, ...)now caches its returnedProviderand hooks so that an HMR re-evaluation of the caller's module reuses the same component identities. Without this, the new module evaluation produced fresh references, React unmounted the existing Provider, all state was lost, and (depending on the file's exports) Vite would fall back to a full page reload or report"useCounterContext" export is incompatible. Closes React Fast Refresh doesn't work on Constate side #146.file:line:column(captured fromnew Error().stackafter skipping constate's own frames by both function name and file path — coveringnode_modules/constate/dist/index.js,node_modules/.vite/deps/constate*.js, and yarn-pnp.ziplayouts) combined with a structural signature ofuseValueand selectors: name, selector count, selector names, and hook counts. The cachedProviderreadsuseValueand selectors through internal refs, so edits to the hook body or selector bodies take effect on the next render while React preserves the Provider's fiber and its hook state. Adding or removing hook calls inuseValueor any selector invalidates the cache entry, preventing React's "rendered more hooks" error at the cost of state loss for that one structural edit.1 + selectorCountref dereferences per Provider render.Test plan
pnpm test— 18 tests pass (the 12 pre-existing tests plus 6 new ones covering identity reuse on matching signature, invalidation onuseValuehook-count change, invalidation on selector hook-count change, independence of two calls on different lines, independence of two calls on the same line, and the cache-skip for anonymoususeValue).pnpm lint— clean.pnpm tsc— clean.pnpm format— clean.examples/src/counter/App.jsx, click the counter a few times, editprevCount + 1toprevCount + N, observe that the count stays at its pre-edit value and the next click applies the new increment. Verified with Vite 8 + React 19; count went from 3 to 103 after changing+ 1to+ 100.🤖 Generated with Claude Code