<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged state</title>
<link>https://coderlegion.com/tag/state</link>
<description>Powered by Question2Answer</description>
<item>
<title>Clean Async State Management with Pinia Colada</title>
<link>https://coderlegion.com/3728/clean-async-state-management-with-pinia-colada</link>
<description>&lt;hr&gt;
&lt;p&gt;Managing async state—think loading spinners, error handling, stale data—is notoriously messy. If you’ve wrestled with nested subscriptions or redundant fetch logic in Vue+Pinia apps, &lt;strong&gt;Pinia Colada&lt;/strong&gt; might be the game-changer you need.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-is-pinia-colada-&quot;&gt;What Is Pinia Colada?&lt;/h3&gt;
&lt;p&gt;Pinia Colada is a powerful data-fetching layer built on top of Pinia. It eliminates boilerplate by providing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Automatic &lt;strong&gt;caching&lt;/strong&gt; and &lt;strong&gt;deduplication&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Smart query &lt;strong&gt;invalidation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Declarative API for &lt;strong&gt;queries&lt;/strong&gt; (data fetches) and &lt;strong&gt;mutations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Support for &lt;strong&gt;optimistic updates&lt;/strong&gt;, SSR, and tree-shaken size of \~2 KB&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;quick-start&quot;&gt;Quick Start&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm install pinia @pinia/colada
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then in your Vue app setup:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import { createPinia } from 'pinia'
import { PiniaColada } from '@pinia/colada'

app.use(createPinia())
app.use(PiniaColada, {/* optional plugins */})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you’re ready to use &lt;code&gt;useQuery&lt;/code&gt; and &lt;code&gt;useMutation&lt;/code&gt; everywhere.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;example-querying-data&quot;&gt;Example: Querying Data&lt;/h3&gt;
&lt;p&gt;Instead of manual loading flags, error state, and fetch logic:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;const { data, error, isPending, isLoading, refresh } = useQuery({
  key: ['users'],
  query: fetchUsers,
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then in the template, you can declaratively handle the three states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;isPending&lt;/code&gt; — first fetch&lt;/li&gt;
&lt;li&gt;&lt;code&gt;isLoading&lt;/code&gt; — refreshes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;error&lt;/code&gt; — if broken&lt;/li&gt;
&lt;li&gt;&lt;code&gt;data&lt;/code&gt; — once resolved&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;mutations-amp-invalidation&quot;&gt;Mutations &amp;amp; Invalidation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;const { mutate: addComment, isLoading } = useMutation({
  mutation: postComment,
  onSettled: async ({ id }) =&amp;gt; {
    await queryCache.invalidateQueries({ key: ['comments', id], exact: true })
  }
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This lets you optimistically update and ensure fresh data before closing modal dialogs or user notifications.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-you-ll-love-it&quot;&gt;Why You’ll Love It&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Minimal state boilerplate: No more juggling &lt;code&gt;isLoading&lt;/code&gt;, &lt;code&gt;isError&lt;/code&gt;, and &lt;code&gt;data&lt;/code&gt; manually.&lt;/li&gt;
&lt;li&gt;Built-in caching and deduplication for better UX and efficiency.&lt;/li&gt;
&lt;li&gt;Fully typed, tree-shakeable, zero deps (besides Pinia), and SSR-ready.&lt;/li&gt;
&lt;li&gt;Plugins like &lt;strong&gt;autoRefetch&lt;/strong&gt; and &lt;strong&gt;delay&lt;/strong&gt; help avoid flickers or stale data.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;real-world-feedback&quot;&gt;Real-World Feedback&lt;/h3&gt;
&lt;p&gt;Reddit users highlight Pinia Colada's advantage for API-driven state:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“This is what Pinia stores call service methods… API calls inside sweet local store. It’s perfect to avoid multiple fetches.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Others note:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;“Pinia is for global app state. For API caching use Tanstack Query… Pinia Colada consolidates the conundrum.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;tl-dr-when-to-use-it&quot;&gt;TL;DR – When to Use It&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Use Pinia Colada when&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You want clean, reusable logic for API calls&lt;/li&gt;
&lt;li&gt;You care about efficient caching and UX consistency&lt;/li&gt;
&lt;li&gt;You prefer declarative state over imperative patterns&lt;/li&gt;
&lt;li&gt;You work with mutable server data and want stale-data control&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;want-to-go-further-&quot;&gt;Want to Go Further?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Explore &lt;strong&gt;optimistic updates&lt;/strong&gt;, SSR support, and GraphQL usage&lt;/li&gt;
&lt;li&gt;Combine with Vue Router Data Loaders and modular async handling&lt;/li&gt;
&lt;li&gt;Try plugins like auto-refetch and delay to polish UX&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;Pinia Colada brings a modern, well-structured approach to async state in Vue apps—cutting boilerplate, reducing bugs, and improving developer happiness. Whether it's simple CRUD or complex dialogs or pagination, it's well worth a look.&lt;/p&gt;
&lt;hr&gt;
</description>
<category>Frontend Dev</category>
<guid isPermaLink="true">https://coderlegion.com/3728/clean-async-state-management-with-pinia-colada</guid>
<pubDate>Sat, 05 Jul 2025 08:33:04 +0000</pubDate>
</item>
<item>
<title>State Management Made Easy with Fluxor in Blazor</title>
<link>https://coderlegion.com/2807/state-management-made-easy-with-fluxor-in-blazor</link>
<description>&lt;p&gt;&lt;strong&gt;Exploring Actions, Effects, and the Benefits of Fluxor&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Modern web applications are becoming increasingly complex, and with complexity comes the need for structured state management. In the world of Blazor a popular .NET-based web UI framework .&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fluxor&lt;/strong&gt; offers a powerful yet easy-to-understand state container that brings predictable state flow to your applications.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fluxor&lt;/strong&gt; is a zero-boilerplate Flux/Redux library for Microsoft .NET.&lt;/p&gt;
&lt;p&gt;It brings the same clean architecture and unidirectional data flow popularized by Redux in the JavaScript ecosystem—adapted for C# developers building with Blazor.&lt;/p&gt;
&lt;p&gt;We’ll break down the core concepts of Fluxor and show how you can use Actions, Reducers, and Effects to create a clean, maintainable architecture.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/stevsharp/BlazorAndFluxorStateMachine&quot;&gt; Explore the GitHub project&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;️ What is Fluxor?&lt;/p&gt;
&lt;p&gt;Fluxor provides a structured and predictable way to manage state in your Blazor application. Inspired by Redux, it embraces:&lt;/p&gt;
&lt;p&gt; Unidirectional data flow — State changes follow a clear path: Action ➝ Reducer ➝ State ➝ UI.&lt;/p&gt;
&lt;p&gt; Single source of truth — All application state lives in a centralized, immutable store.&lt;/p&gt;
&lt;p&gt; Middleware &amp;amp; Effects — Separate side-effects like API calls from your UI and business logic.&lt;/p&gt;
&lt;p&gt;Unlike some Redux implementations, Fluxor handles a lot of the boilerplate for you with C#-friendly conventions and strong typing.&lt;/p&gt;
&lt;p&gt; Actions – Declaring Intent&lt;/p&gt;
&lt;p&gt;In both Redux and Fluxor, Actions are plain messages that describe what happened. They're just &lt;br&gt;
signals , they don’t contain logic.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public record FetchItemsAction;
public record FetchItemsSuccessAction(List&amp;lt;Item&amp;gt; Items);
public record FetchItemsFailedAction(string ErrorMessage);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;⚙️ Effects – Handling Side Effects&lt;/p&gt;
&lt;p&gt;Since Reducers must be pure, Effects in Fluxor allow you to perform async operations like API calls without cluttering your UI.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public class ItemEffects
{
    [EffectMethod]
    public async Task HandleFetchItems(FetchItemsAction action, IDispatcher dispatcher)
    {
        try
        {
            var items = await itemService.GetItemsAsync();
            dispatcher.Dispatch(new FetchItemsSuccessAction(items));
        }
        catch (Exception ex)
        {
            dispatcher.Dispatch(new FetchItemsFailedAction(ex.Message));
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This Effect reacts to FetchItemsAction and handles fetching data from an external service.&lt;/p&gt;
&lt;p&gt; State and Reducers – Updating the Store&lt;/p&gt;
&lt;p&gt;Reducers are responsible for updating state in response to actions. They are pure functions and return a new state based on the action received.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public static class ItemReducers
{
    [ReducerMethod]
    public static ItemState OnFetchSuccess(ItemState state, FetchItemsSuccessAction action) =&amp;gt;
        state with { Items = action.Items, IsLoading = false };

    [ReducerMethod]
    public static ItemState OnFetchFailed(ItemState state, FetchItemsFailedAction action) =&amp;gt;
        state with { ErrorMessage = action.ErrorMessage, IsLoading = false };
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Reducers never mutate state—they return a new state object.&lt;/p&gt;
&lt;p&gt; Try It Yourself&lt;/p&gt;
&lt;p&gt;Check out the working example project to see all these concepts in action:&lt;br&gt;
 &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/stevsharp/BlazorAndFluxorStateMachine&quot;&gt;https://github.com/stevsharp/BlazorAndFluxorStateMachine&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;It demonstrates:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dispatching Actions from UI&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handling async logic with Effects&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clean Reducer logic&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Blazor component integration&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;✅ Why Use Fluxor?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No boilerplate overload – clean C# syntax&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clear, testable state transitions&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great for scaling large Blazor apps&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Familiar to those who’ve used Redux in React or Angular&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keeps business logic and UI concerns separate&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt; References&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mrpmorris/Fluxor&quot;&gt;Fluxor GitHub Repository&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://redux.js.org/&quot;&gt;Redux Official Site&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://angular-redux.js.org/&quot;&gt;Angular Redux&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/stevsharp/BlazorAndFluxorStateMachine&quot;&gt;Blazor Documentation – Microsoft&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;BlazorAndFluxorStateMachine – GitHub Sample&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;List item&lt;/li&gt;
&lt;/ul&gt;
</description>
<category>C#</category>
<guid isPermaLink="true">https://coderlegion.com/2807/state-management-made-easy-with-fluxor-in-blazor</guid>
<pubDate>Fri, 25 Apr 2025 12:59:35 +0000</pubDate>
</item>
</channel>
</rss>