BlazorApp Blazor Server 프로젝트 생성Blazor를 실행하면 Counter 메뉴에서 카운트를 증가시킬 수 있습니다.
하지만 다른 페이지로 이동 후 다시 돌아오면 Count 값이 초기화됩니다.
이 문제를 해결하기 위해 Scoped 서비스로 상태를 유지해보겠습니다.
Data/CounterState.cs
namespace BlazorApp.Data
{
public class CounterState
{
public int Count { get; set; }
}
}
Count 프로퍼티는 외부에서 get/set 가능builder.Services.AddScoped<CounterState>();
Scoped로 등록했기 때문에, 사용자 세션마다 별도의 인스턴스로 동작합니다.@page "/counter"
@inject BlazorApp.Data.CounterState CounterState
<h1>Counter</h1>
<p>Current count: @CounterState.Count</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private void IncrementCount()
{
CounterState.Count++;
}
}
@inject를 통해 CounterState 주입Count를 증가시킴✅ 이 상태에서는 다른 메뉴로 이동 후 다시 Counter로 돌아와도 값이 유지됩니다.
이제 NavMenu.razor에서 현재 Count 값을 표시해보겠습니다.
@inject BlazorApp.Data.CounterState CounterState
<p style="color:white">Counter: @CounterState.Count</p>
Counter를 증가시켜도 여기 값은 갱신되지 않음왜?
→ Blazor는 값이 변경되어도 수동으로 StateHasChanged()를 호출하지 않으면 UI를 갱신하지 않음
public class CounterState
{
private int _count = 0;
public Action? OnStateChanged;
public int Count
{
get => _count;
set
{
_count = value;
Refresh();
}
}
private void Refresh() => OnStateChanged?.Invoke();
}
Refresh() 호출OnStateChanged를 통해 이벤트 구독자에게 알림@inject BlazorApp.Data.CounterState CounterState
@implements IDisposable
<p style="color:white">Counter: @CounterState.Count</p>
@code {
protected override void OnInitialized()
{
CounterState.OnStateChanged += Update;
}
void Update()
{
StateHasChanged(); // 수동 갱신
}
public void Dispose()
{
CounterState.OnStateChanged -= Update; // 구독 해제
}
}
+=)StateHasChanged()로 수동 트리거Dispose()에서 구독 해제