Repository navigation
fix(mobile): don't leave the splash up when the preload beats the first effect - #14658
Merged
Merged
Conversation
…st effect App's useEffectOnce skipped subscribing to localStoragePreloadPromise when the module-level flag was already true. If the preload resolved after the first render (preloaded=false) but before the effect ran, nothing ever set the state, so App rendered null and the splash stayed up. Subscribing unconditionally is safe: setPreloaded(true) is idempotent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This was referenced Oct 9, 2026
dylanjeffers
marked this pull request as ready for review
October 9, 2026 23:49
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
Cold launches can stay on the splash screen forever.
Apprendersnulluntil the AsyncStorage preload finishes, and itsuseEffectOnceonly subscribed tolocalStoragePreloadPromisewhen the module-levellocalStoragePreloadedflag was still false. If the preload resolves after the first render but before the effect runs, the flag is already true, the effect skips the subscription, and nothing ever setspreloaded.Appkeeps returningnull,RootScreennever mounts, andBootSplash.hideis never called.The fix subscribes unconditionally.
setPreloaded(true)is idempotent, so the extra.thenon an already-resolved promise costs nothing.Why now
Found while smoke-testing the New Architecture flip (#14657). On the new architecture, passive effects run later relative to the first render, which opens the window. On the iOS 26.5 simulator with the 1.5.189 new-arch Release build:
RCTRootComponentViewwith no children). Instrumented runs loggedApp render preloaded=false, thenpreload resolved, and no further render.The same race exists on the old architecture (introduced in #14259). It just loses it less often. 3 of 3 old-arch 1.5.188 launches were fine.
Rollout
JS-only. It's safe to OTA to 1.5.188. It has to be on main before #14656 / #14657 merge, so the 1.5.189 binary ships with it. Rebase or merge main into
chore/mobile-native-release-1.5.189after this lands.Checks
packages/mobile/src/app/App.tsx: passnpx tsc --noEmit -p packages/mobile: pass🤖 Generated with Claude Code