SourceGeneration.Blazor.State 1.0.0-beta4.250310.1

This is a prerelease version of SourceGeneration.Blazor.State.
dotnet add package SourceGeneration.Blazor.State --version 1.0.0-beta4.250310.1                
NuGet\Install-Package SourceGeneration.Blazor.State -Version 1.0.0-beta4.250310.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SourceGeneration.Blazor.State" Version="1.0.0-beta4.250310.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add SourceGeneration.Blazor.State --version 1.0.0-beta4.250310.1                
#r "nuget: SourceGeneration.Blazor.State, 1.0.0-beta4.250310.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install SourceGeneration.Blazor.State as a Cake Addin
#addin nuget:?package=SourceGeneration.Blazor.State&version=1.0.0-beta4.250310.1&prerelease

// Install SourceGeneration.Blazor.State as a Cake Tool
#tool nuget:?package=SourceGeneration.Blazor.State&version=1.0.0-beta4.250310.1&prerelease                

Blazor State

NuGet

Blazor state and action framework base on ChangeTracking and ActionDispather, and it supports AOT compilation

Installing

This library uses C# preview features partial property, Before using this library, please ensure the following prerequisites are met:

  • Visual Studio is version 17.11 preview 3 or higher.
  • To enable C# language preview in your project, add the following to your .csproj file
<PropertyGroup>  
  <LangVersion>preview</LangVersion>  
</PropertyGroup>  
Install-Package SourceGeneration.Blazor.State -Version 1.0.0-beta4.250107.1
dotnet add package SourceGeneration.Blazor.State --version 1.0.0-beta4.250107.1

DependencyInjection

services.AddBlazorState();

State Management

This library uses SourceGeneration.ChangeTracking for state management. view document.

Defining state

[ChangeTacking]
public partial class MyState : State<MyState>
{
    public partial int Count { get; set; }
}

using services inject

//WebAssembly or Hybird
services.AddSingleton<MyState>();

//Server
services.AddScoped<MyState>();

Component

Inherits StateComponentBase, StateComponentBase automatically invokes StateHasChanged when after state binding has changed.

By default, which automatically invokes StateHasChanged after the component's event handlers are invoked. In scenarios where rendering is automatically handled through state management, triggering a rerender after an event handler is invoked is often unnecessary or undesirable. Override ShouldRenderOnEventHandled to control the behavior of Blazor's event handling.

@inherits StateComponentBase
@inject MyState State

<p>Current count: @State.Count</p>

<button @onclick="IncrementCount">Click me</button>

@code{
    private int currentCount;

    protected override bool ShouldRenderOnEventHandled() => false;

    protected override void OnInitialized()
    {
        //Subscribe state.Count property
        Watch(State, x => x.Count);
    }

    private void IncrementCount()
    {
        State.Count++;
        State.AcceptChanges();
    }
}

Note Don't directly update State within the Component. The code provided here is just an example of State. Instead, you should dispatch actions and update State within the action handler.

Change Scope

Consider the following scenario where a component binds to an UndoList, and the Undo object and List are rendered in the same component without using child components. When we modify the Undo property, we need to rerender the page. This can be achieved using ·ChangeTrackingScope.Cascading`.

You can specify the scope of the subscribed changes.

  • ChangeTrackingScope.Root default value
    The subscription only be triggered when there are changes in the properties of the object itself.
  • ChangeTrackingScope.Cascading
    The subscription will be triggered when there are changes in the properties of the object itself or in the properties of its property objects.
  • ChangeTrackingScope.Always
    The subscription will be triggered whenever the Update method is called, regardless of whether the value has changed or not.
@inherits StateComponentBase
@inject UndoState State

<ul>
    @foreach(var undo in UndoList)
    {
        <li>
            <h5>@undo.Title</h5>
            <p>@undo.Done</p>
            <button @onclick="@(() => UpdateTitle(undo.Id))">Update</button>
        </li>
    }
</ul>

@code{
    private ChangeTrackingList<Undo> UndoList;

    protected override bool ShouldRenderOnEventHandled() => false;

    protected override OnInitialized()
    {
        //ChangeTrackingScope.Cascading
        Watch(State, x => x.List, x => UndoList = x, ChangeTrackingScope.Cascading);
    }

    private void UpdateTitle(int id)
    {
        State.List.First(x => x.Id == id).Title = "title changed";
        State.AccpetChanges();
    }
}

At another scenario where we delegate the rendering of the Undo object to a separate child component called UndoComponent. When a property of a specific Undo object changes, we don't want to trigger the rendering of the list component. This can be achieved using ChangeTrackingScope.Root.

@inherits StateComponentBase
@inject UndoState State

<div>
    @foreach(var undo in UndoList)
    {
        <UndoComponent Id="@undo.Id" />
    }
</div>

<button @onclick="AddUndo">Add Undo</button>

@code{
    private ChangeTrackingList<Undo> UndoList;

    protected override bool ShouldRenderOnEventHandled() => false;

    protected override OnInitialized()
    {
        //ChangeTrackingScope.Root
        Watch(State, x => x.List, x => UndoList = x, ChangeTrackingScope.Root);
    }

    private void AddUndo()
    {
        State.List.Add(new Undo());
        State.AcceptChanges();
    }
}

Action Dispatcher

This library uses SourceGeneration.ActionDispatcher for event dispatch & subscribe. view document.

Defining action

public class Increment
{
    // Parameters
}

Defining action handler

public class DefaultActionHandler(MyState state)
{
    [ActionHandler]
    public void Handle(Increment action)
    {
        state.Count++;
        state.AcceptChanges();
    }
}

Action Subscriber

@inherits StateComponentBase

@code{
    protected void OnInitialized()
    {
        SubscribeAction<Increment>(action => 
        {
            //Do something
        });
    }
}

Features

  • Based on Source Generator, it's faster and AOTable
  • Not an implementation of Redux, it's simpler and easier to use.
  • Supports ChangeScope, it will be minimize calls to StateHasChanged as much as possible
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.0-beta4.250310.1 120 16 days ago
1.0.0-beta4.250303.1 53 23 days ago
1.0.0-beta4.250302.1 50 24 days ago
1.0.0-beta4.250107.1 52 3 months ago