<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-rbvpu9dvv" -->

---
title: From Click to State: the Store/Action Pattern Behind a...
description: A deep-dive into a Store/Action pattern for state management in a Compose Multiplatform app, showing how to separate a frozen dispatcher, a neutral...
canonical: https://daily.dev/posts/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-rbvpu9dvv
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: From Click to State: the Store/Action Pattern Behind a Compose Multiplatform App | daily.dev
og:description: A deep-dive into a Store/Action pattern for state management in a Compose Multiplatform app, showing how to separate a frozen dispatcher, a neutral...
og:url: https://daily.dev/posts/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-rbvpu9dvv
og:image: https://api.daily.dev/og/posts/rBvPu9DVv.png
og:image:alt: From Click to State: the Store/Action Pattern Behind a Compose Multiplatform App
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# From Click to State: the Store/Action Pattern Behind a Compose Multiplatform App

**[Medium](https://daily.dev/sources/medium_js)** · 12 min read · 0 upvotes · 0 comments

## Summary

A deep-dive into a Store/Action pattern for state management in a Compose Multiplatform app, showing how to separate a frozen dispatcher, a neutral state-holding store, and one-file-per-intent actions. Covers building the core Store/StoreAction/StoreViewModel abstractions, then applying them to data loading and pagination via Flow, nested component state updates using state trees, and navigation as just another dispatched action. Demonstrates with a real open-source Rick and Morty Compose Multiplatform sandbox targeting Android, iOS, desktop and web.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@math.perroud/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-8a0e3499ba98>

## Questions this post answers

### How do I structure state management in a Compose Multiplatform app without bloating the ViewModel?

Split responsibilities into three pieces: a frozen dispatcher (onAction), a neutral Store that only holds state and exposes structural helpers like updateState, fetchData, and collectData, and one StoreAction file per user intent that injects its own dependencies and mutates state. The ViewModel shrinks to a lifecycle adapter that forwards actions to the store, staying at roughly three lines even as intents grow.

_daily.dev surfaces architecture write-ups like this for teams shaping their own Compose state patterns._

### How should pagination be handled when using Kotlin Flow for loading a character list?

Subscribe once to the data source as a Flow during initial load, then let a separate LoadMoreCharacters action only manage loading flags (isLoadingMore, loadingMoreError) around a fetchData call, while new items arrive automatically through the same Flow subscription opened at initialization. This keeps the pagination action from ever touching list content directly, and lets the same use case be shared across multiple stores like a portrait list and landscape dashboard.

_developers comparing pagination approaches often track patterns like this one on daily.dev._

### How can screen state represent nested component states like a list and a detail pane together?

Model screen state as a tree where each leaf is an existing component's UiState, plus one extra screen-level type for facts components cannot know, such as whether any item is selected. Actions then replace only the relevant subtree with a copy, for example swapping in a loading or loaded detail state while leaving the list subtree untouched, preserving scroll position and pagination flags across selections.

_daily.dev helps developers keep up with state-tree patterns for multi-pane Compose layouts._

## Similar posts on daily.dev

- [AppState in Jetpack Compose: The Missing Piece for Building Large-Scale Android Apps](https://daily.dev/posts/appstate-in-jetpack-compose-the-missing-piece-for-building-large-scale-android-apps-gsrhvyqeq) · Medium · 2 upvotes · 1 comments
- [In Defense of Redux](https://daily.dev/posts/in-defense-of-redux-pcyqzgarj) · ITNEXT · 1 upvotes · 0 comments
- [Where Should Initial Load Logic Actually Live in Jetpack Compose?](https://daily.dev/posts/where-should-initial-load-logic-actually-live-in-jetpack-compose--hcfvjbgh6) · ProAndroidDev · 3 upvotes · 0 comments
- [15 Years of Android App Architectures](https://daily.dev/posts/15-years-of-android-app-architectures-1xg7is4ou) · droidcon · 0 upvotes · 0 comments

---

Tags: [#architecture](https://daily.dev/tags/architecture), [#kotlin](https://daily.dev/tags/kotlin), [#jetpack-compose](https://daily.dev/tags/jetpack-compose)

[View this post on daily.dev](https://daily.dev/posts/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-rbvpu9dvv)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"From Click to State: the Store/Action Pattern Behind a Compose Multiplatform App","url":"https://daily.dev/posts/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-rbvpu9dvv","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-rbvpu9dvv"},"datePublished":"2026-08-21T22:08:45.127Z","dateModified":"2026-08-21T22:21:59.310Z","description":"A deep-dive into a Store/Action pattern for state management in a Compose Multiplatform app, showing how to separate a frozen dispatcher, a neutral...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/582100335dc5f32801b23e0989c92bda?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/582100335dc5f32801b23e0989c92bda?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-rbvpu9dvv","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"architecture,kotlin,jetpack-compose","timeRequired":"PT12M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"From Click to State: the Store/Action Pattern Behind a Compose Multiplatform App"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/from-click-to-state-the-store-action-pattern-behind-a-compose-multiplatform-app-rbvpu9dvv#faq","mainEntity":[{"@type":"Question","name":"How do I structure state management in a Compose Multiplatform app without bloating the ViewModel?","acceptedAnswer":{"@type":"Answer","text":"Split responsibilities into three pieces: a frozen dispatcher (onAction), a neutral Store that only holds state and exposes structural helpers like updateState, fetchData, and collectData, and one StoreAction file per user intent that injects its own dependencies and mutates state. The ViewModel shrinks to a lifecycle adapter that forwards actions to the store, staying at roughly three lines even as intents grow. daily.dev surfaces architecture write-ups like this for teams shaping their own Compose state patterns."}},{"@type":"Question","name":"How should pagination be handled when using Kotlin Flow for loading a character list?","acceptedAnswer":{"@type":"Answer","text":"Subscribe once to the data source as a Flow during initial load, then let a separate LoadMoreCharacters action only manage loading flags (isLoadingMore, loadingMoreError) around a fetchData call, while new items arrive automatically through the same Flow subscription opened at initialization. This keeps the pagination action from ever touching list content directly, and lets the same use case be shared across multiple stores like a portrait list and landscape dashboard. developers comparing pagination approaches often track patterns like this one on daily.dev."}},{"@type":"Question","name":"How can screen state represent nested component states like a list and a detail pane together?","acceptedAnswer":{"@type":"Answer","text":"Model screen state as a tree where each leaf is an existing component's UiState, plus one extra screen-level type for facts components cannot know, such as whether any item is selected. Actions then replace only the relevant subtree with a copy, for example swapping in a loading or loaded detail state while leaving the list subtree untouched, preserving scroll position and pagination flags across selections. daily.dev helps developers keep up with state-tree patterns for multi-pane Compose layouts."}}]}
```

