Skip to content

fix(compose): lazy list keys, stale remember, redundant derivedStateOf#851

Merged
bmc08gt merged 14 commits into
code/cashfrom
fix/compose-keys-state-derivedstate
Jun 4, 2026
Merged

fix(compose): lazy list keys, stale remember, redundant derivedStateOf#851
bmc08gt merged 14 commits into
code/cashfrom
fix/compose-keys-state-derivedstate

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add stable key to lazy list items() in TokenDetails (social links) and BackgroundControls (color options grid)
  • Remove redundant derivedStateOf wrappers where the block reads plain parameters instead of snapshot State objects (NavigationBar, TransactionReceipt, TokenList)
  • Add missing remember keys to prevent stale cached values when inputs change (LabsScreen, TokenDiscoveryScreen, Editors — all three editor composables)

8 files changed, 15 insertions, 28 deletions.

🤖 Generated with Claude Code

bmc08gt and others added 14 commits June 4, 2026 10:24
onConfirm was captured by a LaunchedEffect(Unit) without
rememberUpdatedState. If the caller recomposes with a new lambda,
the stale version executes on swipe-to-confirm.
Wrap sortedBy/groupBy, map, and forEachIndexed transforms in
remember(key) so they do not re-run on every recomposition inside
LazyColumn item factories.
Last remaining collectAsState() call in production code. Stops flow
collection when the app is backgrounded.
Replace mutableStateOf(0L) with mutableLongStateOf(0L) to avoid
Long autoboxing on every state read.
Replace Modifier.alpha(animatedFloat) and Modifier.rotate(animatedFloat)
with graphicsLayer equivalents so animated values are read in the draw
phase instead of triggering recomposition every frame.
…ection

Replace LaunchedEffect(Unit) with LaunchedEffect(viewModel) so the
effect restarts if the ViewModel instance changes, and is consistent
across composables.
Add key parameters to items() calls in DeviceLogsScreen, UserFlagsEditor,
FrequentlyUsedEmojis, and EmojiSearch so Compose can diff items correctly
during recomposition instead of recomposing every item.
Replace remember with rememberSaveable for isExportSeedRequested and
isStoragePermissionGranted so these flags survive configuration changes.
LocalAppUpdater and LocalCoinbaseOnRampController are provided once at
app startup and never change. Using staticCompositionLocalOf avoids
unnecessary recomposition tracking overhead.
Reorder parameters to follow Compose API guidelines: required params
first, then modifier, then optional params, then trailing lambdas.
Also fix modifier chain ordering in Pill and CodeToggleSwitch so the
caller modifier is applied outermost.
Shared reusable component was missing a modifier parameter, preventing
callers from controlling its layout.
LaunchedEffect(Unit) was reading state.customizations and
state.purchaseAmount but only running once. Key on these values
so the effect re-fires when they change.
… wrappers

With Strong Skipping Mode enabled, the remember-based lambda caching in
rememberedClickable is redundant — Compose auto-stabilizes lambdas. The
Modifier.composed wrapper also allocates a sub-composition per element
per recomposition.

- Delete both rememberedClickable overloads from Modifier.kt
- Rename rememberedLongClickable to longClickable (no composed)
- Simplify noRippleClickable (no composed, null interactionSource)
- Keep unboundedClickable (needs composed for @composable ripple())
- Migrate 38 call sites across the codebase:
  - Simple .rememberedClickable -> .clickable (standard foundation)
  - No-ripple pattern -> .noRippleClickable
  - Long click -> .longClickable
- Remove unused MutableInteractionSource imports
…t derivedStateOf

- Add stable `key` to lazy list items in TokenDetails and BackgroundControls
- Remove redundant `derivedStateOf` wrappers where the block reads no
  snapshot State (NavigationBar, TransactionReceipt, TokenList)
- Add missing `remember` keys to prevent stale cached values
  (LabsScreen, TokenDiscoveryScreen, Editors)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added type: fix Bug fix area: payments Payments, transfers, intents, billing area: ui Compose UI, theme, components, resources area: tokens Token accounts, balances, token info labels Jun 4, 2026
Base automatically changed from refactor/remove-composed-clickables to code/cash June 4, 2026 15:52
@bmc08gt bmc08gt merged commit 0684ddc into code/cash Jun 4, 2026
3 checks passed
@bmc08gt bmc08gt deleted the fix/compose-keys-state-derivedstate branch June 4, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: payments Payments, transfers, intents, billing area: tokens Token accounts, balances, token info area: ui Compose UI, theme, components, resources type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant