[Blazor] 상태 관리 라이브러리

종류

MSDN | https://docs.microsoft.com/ko-kr/aspnet/core/blazor/state-management?view=aspnetcore-6.0&pivots=webassembly


상태 관리 라이브러리 사용 이유

  • Smart Component(page) 에서 자식 컴포넌트에서 내려준 Props 는 Page 에서 생성된 데이터입니다. 새로고침 시 데이터가 리셋 되는 현상을 막기 위해서 어딘가에 영구적으로 데이터를 저장해야 합니다. 상태 관리 라이브러리는 이러한 기능을 제공합니다.
  • Component Depth 가 깊어지면 부모 컴포넌트로부터 데이터를 받아오는 로직이 너무 길어집니다. 데이터를 넣고 빼기 쉽게 하기 위하여 사용합니다.
  • 페이지 A 에서 발생한 데이터 변경을 페이지 B 에 반영하기 위한 이유에서 사용합니다.
  • 데이터 처리 Flow 를 하나의 클래스(함수) 에서 처리하여 관리 포인트를 줄이기 위해서 사용합니다.

Blazor - Fluxor

  • 다양한 상태 관리 라이브러리가 있지만, 이 중에서 Fluxor 라이브러리 사용 방법에 대해서 정리 합니다.
  • Fluxor 는 Action 이 발생하면 연관된 다른 곳도 자동으로 상태가 변경되도록 도와주는 라이브러리입니다.


Nuget Package Setup

  • Nuget 에서 Fluxor 를 검색하여 다음 항목들을 추가합니다. (5.5.0 version사용. NET 6.0 기준)
    • Fluxor
    • Fluxor.Blazor.Web
    • Fluxor.Blazor.Web.ReduxDevTools


Program.cs

using Fluxor;

var builder = WebApplication.CreateBuilder(args);
//... 중략..

var currentAssembly = typeof(Program).Assembly;// 추가
builder.Services.AddFluxor(options => options.ScanAssemblies(currentAssembly)); // 추가
//... 중략..

var app = builder.Build();
//... 중략..

app.Run();

Store 생성

  • 다음으로 State, Action, Reducer 를 생성합니다.
  • 아래와 디렉터리 구조가 같을 필요는 없습니다.

/// State
[FeatureState]
public class CounterState
{
    public int Count { get; set; }

    private CounterState() 
    { 

    }

    public CounterState(int count)
    {
        Count = count;
    }

}

/// Action
public class IncrementCounterAction
{
}

/// Reducers
namespace FluxExample.Store;

public static class Reducers
{
    //[ReducerMethod]
    //public static CounterState ReduceIncrementCounterAction(CounterState state, IncrementCounterAction action) =>
    //        new(count: state.Count + 1);

    [ReducerMethod(typeof(IncrementCounterAction))]
    public static CounterState OnIncrement(CounterState state)
    {
        return new CounterState(count: state.Count + 1);
    }
}

State 값 가져오기.

  • 이제 State 값을 가져오기 위해서, Counter.razor 페이지로 이동합니다.
  • razor 페이지에 아래와 같이 값을 입력하면 값을 가져 올 수 있습니다.
  • IoC 처리는 Reducer Attribute 와 상호작용합니다.
<div>
    <span>store에서 온 값 : </span>
    <span>@Sate.Value.Count</span>
</div>

@code{
    [Inject]
    public IState<CounterState> Sate { set; get; }
}

State 값 변경하기

  • Store 내 모든 변경 행위는 Dispatcher 를 통해서 Reducer 에서 이루어집니다.
  • razor 페이지로 이동하여 Dispatcher 를 주입 받습니다.
  • 버튼 Event 에서 Dispatcher 로 Count 를 변경하는 코드를 추가합니다.
<button class="btn btn-primary" @onclick="OnStateChange">Reducer에서 변경.</button>

@Code{
    [Inject]
    public IDispatcher Dispatcher { get; set; }


    public void OnStateChange()
    {    
        this.Dispatcher.Dispatch(new IncrementCounterAction());
    }
}
  • Counter.razor 페이지의 전체 코드는 다음과 같습니다.
@page "/counter"
@using FluxExample.Store

<PageTitle>Counter</PageTitle>

<h1>Counter</h1>

<button class="btn btn-primary" @onclick="OnStateChange">Reducer 에서 변경.</button>

<div>
    <span>store에서 온 값 : </span>
    <span>@State!.Value.Count</span>
</div>

@code {
    [Inject]
    public IDispatcher? Dispatcher { get; set; }

    [Inject]
    public IState<CounterState>? State { get; set; }

    public void OnStateChange()
    {
        this.Dispatcher!.Dispatch(new IncrementCounterAction());
    }
}

실행 결과

  • 페이지를 이동해도 Stroe 에서 온 값은 Reset 되지 않고 유지되는 것을 확인할 수 있습니다.

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY