Blazor WASM - 레이아웃과 페이지 간의 공유 상태

구성 요소(예: 페이지 및 레이아웃) 간에 상태 데이터를 쉽게 공유할 수 있지만 둘 중 하나에서 데이터를 변경해도 필요한 경우 다른 하나가 자동으로 다시 렌더링되지는 않습니다.

  • 데이터가 포함된 클래스를 만듭니다.

    using System.Collections.ObjectModel;
    
    public class NamesService{
        private readonly List<string> _names = new List<string>();
        public ReadOnlyCollection<string> Names { 
            get { return _names.AsReadOnly(); } 
        } 
        public event Action? StateChanged;
        public void AddName(string name) {
            _names.Add(name); 
            StateChanged?.Invoke(); //raise the event
        }
    }
    

    이벤트를 사용하고 있습니다. 이 클래스의 종속 항목(blazor 구성 요소)은 StateChanged 이벤트를 구독해야 합니다.

    데이터를 직접 추가하는 것을 피하기 위해 읽기 전용 컬렉션을 반환하고 있다는 점에 유의하십시오. 종속 항목은 대신 AddName를 사용하여 이벤트를 트리거해야 합니다.

  • DI에 상태 컨테이너를 Singleton으로 등록합니다. 귀하의 Program.cs .

    builder.Services.AddSingleton<NamesService>();
    

    페이지를 전환할 때마다 NamesService의 새 인스턴스를 만들고 싶지 않기 때문에 싱글톤으로 만듭니다.

  • 구성 요소에서 StateChanged 이벤트를 구독합니다. 예를 들어 레이아웃에서:

    @inherits LayoutComponentBase
    @implements IDisposable
    @inject NamesService NamesService
    <!-- some code goes here -->
    <span>@NamesState.Names.Count</span>
    <button @onclick="Add">Add</button>
    <!-- some code goes here -->
    @Body
    <!-- some code goes here -->
    @code {
        protected override void OnInitialized() {
            NamesService.StateChanged += this.StateHasChanged; // subscribe
        }
        protected void Add() {
            NamesService.Add("from layout: " + DateTime.UtcNow.ToString()); // add random data
        }
        public void Dispose() {
            NamesService.StateChanged -= this.StateHasChanged; // unsubscribe
        }
    }
    

    참고 사항:
  • @inject를 사용하여 NamesService 인스턴스를 가져옵니다.
  • 구성 요소가 초기화되면( OnInitialized ) 구성 요소의 NamesService.StateChanged 메서드를 사용하여 StateHasChanged를 구독합니다.
  • 페이지가 삭제될 때 IDisposable에서 구독을 취소할 수 있도록 NamesService.StateChanged를 구현합니다.

  • 우리 페이지에서는 동일합니다.

    @page "/test"
    @implements IDisposable
    @inject NamesService NamesService
    <ul>@foreach(var name in NamesState.Names)
    { <li>@name</li> }
    </ul>
    <button @onclick="Add">Add</button>
    @code {
        protected override void OnInitialized() {
            NamesService.StateChanged += this.StateHasChanged; // subscribe
        }
        protected void Add() {
            NamesService.Add("from page: " + DateTime.UtcNow.ToString()); // add random data
        }
        public void Dispose() {
            NamesService.StateChanged -= this.StateHasChanged; // unsubscribe
        }
    }
    


    요약하면 NamesService.Add()가 호출되면 이벤트 NamesService.StateChanged가 발생하고 이벤트의 모든 구독자에게 알림이 전송되며 이 예에서는 구성 요소의 StateHasChanged가 호출됩니다.

    우리의 구성 요소는 이제 데이터를 추가할 수 있으며 변경 사항은 모든 구독 구성 요소에 반영되어야 합니다.

    자원

    Microsoft Docs - Event
    Microsoft Docs - Service Lifetime
    Microsoft Docs - StateHasChanged
    Microsoft Docs - State Management

    좋은 웹페이지 즐겨찾기