Persisting Fluxor state in Blazor WASM
Tags: dotnet, blazor, fluxor, webassembly
Published: 2023-08-29 20:49:04

---
title: Persisting Fluxor state in Blazor WASM
published: true
description: It’s all fun and games until someone hits F5
tags: dotnet,blazor,fluxor,wasm
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-08-28 19:58 +0000
---

If you are using Blazor WebAssembly with Fluxor, you will likely have come across the situation where refreshing the current page wipes out your state and sets it back to defaults. 

This is not unique to Blazor/Fluxor - it happens in React/Redux too - but it’s a behaviour that is guaranteed to frustrate users.

This is one approach you can take to ensure that a browser refresh doesn't wipe out your Fluxor state.

## Prerequisites

The following assumes you already have a Blazor WebAssembly project set up with Fluxor. If not, head over to https://github.com/mrpmorris/Fluxor and get started.

## Step 1 - Session storage

First off we need to install Blazored.SessionStorage following the instructions at https://github.com/Blazored/SessionStorage. This gives us the core functionality to read and write objects to the browser’s Session Storage.

```
builder.Services.AddBlazoredSessionStorageAsSingleton();
```

## Step 2 - Add a new action and reducer

At the heart of Fluxor are actions which mutate state via reducers. The beauty of actions is they can pass any object on their properties.

Normally an action would pass properties specific to a state, but this time we want an action that passes the state itself.

```
public record LoadUsersFromStorageAction(UsersState storedState);
```

Now that the action is created, we need to mutate the state in the reducer using the state object on the action.

```
[ReducerMethod]
        public static UsersState ReduceLoadUsersFromStorageAction(UsersState state, LoadUsersFromStorageAction action)
        {
            return state with
            {
                ErrorMessage = action.storedState.ErrorMessage,
                LoadingStatus = action.storedState.LoadingStatus,
                Users = action.storedState.Users
            };
        }
```

## Step 3 - Add a new wrapper component 

Create a new Razor component called something like **FluxorSessionStorage.razor** that is going to handle the reads and writes e.g.

```
@inject IDispatcher _dispatcher;
@inject ISyncSessionStorageService _sessionStorage;
@inject IState<UsersState> _usersState;

@ChildContent

@code {
    protected override void OnInitialized()
    {
		// read
        var savedState = _sessionStorage.GetItem<UsersState>("UsersState");
        if (savedState != null)
        {
            _dispatcher.Dispatch(new LoadUsersFromStorageAction(savedState));
        }

        // write
        _usersState.StateChanged += ((state, e) =>
        {
            var data = ((IState<UsersState>)state).Value;
            _sessionStorage.SetItem<UsersState>("UsersState", data);
        });
    }

    [Parameter] public RenderFragment? ChildContent { get; set; }
}
```

As you can see, the OnInitialized method is used to wire up the storage methods. These methods are only called when the component is loaded on refresh.

The component will wrap the entire Blazor app thereby capturing all the Fluxor activity.

```
<Fluxor.Blazor.Web.StoreInitializer />
<CascadingAuthenticationState>
    <FluxorSessionStorage>
        <Router AppAssembly="@typeof(App).Assembly">
            <Found Context="routeData">
                <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
                <FocusOnNavigate RouteData="@routeData" Selector="h1" />
            </Found>
            <NotFound>
                <PageTitle>Not found</PageTitle>
                <LayoutView Layout="@typeof(MainLayout)">
                    <p role="alert">Sorry, there's nothing at this address.</p>
                </LayoutView>
            </NotFound>
        </Router>
    </FluxorSessionStorage>
</CascadingAuthenticationState>
```

## Step 4 - Test it

Now when we run the application, we should see our Fluxor state being persisted in the browser's Session Storage.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/psdb7pd2x67nqr9hgpmc.png)

If we make any change to the state, we trigger a write to Session Storage.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lz2l2iwa9y87tunyj7p8.png)

Likewise, if we hit F5, we load the state from Session Storage.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zjtqevq8w6tkbqdghdun.png)