Blazor EventCallBack<T>에 대해 질문이 있습니다.

// Board.razor
<Modal IsOpenChanged="Manager.UpdateModalState" />


// Modal.razor
@inject GameManagerService Manager;
@if (!Manager.IsModalOpen) return;
<div class="modal-body"> ~~~ </div>

@code {
[Parameter] public EventCallback<bool> IsOpenChanged { get; set; }
}


// GameManagerService.cs
public bool IsModalOpen { get; set; }
private void OpenModal() => IsModalOpen = true;
public void UpdateModalState(bool isOpen) => IsModalOpen = isOpen;

위의 코드에서는 OpenModal 메서드를 호출했을 때 모달창이 띄워지는 것을 확인했습니다.
이때 IsOpenChanged 이벤트를 제거하게 되면 모달창이 띄워지질 않습니다.

코드만 봤을 때는 UpdateModalState 메서드를 사용하는 곳이 Board.razor에서 IsOpenChaged 프로퍼티로 GameManagerService의 UpdateModalState 메서드를 넘겨주는 부분 밖에 없는것 같은데 왜 이부분을 제거하면 모달이 띄워지질 않는걸까요? 이 부분을 제거하면 브레이크 포인트를 찍어 보았을 때Modal.razor로 진입을 하지도 않습니다.
Blazor 공식문서 - EventCallBack를 참고해 봐도 관련된 내용은 안보이는데 EventCallBack에 등록된 메서드에서 사용되는 프로퍼티는 모두 다 추적관리가 되는건가요?

1 Like

이벤트가 발생하면 해당 컴포넌트를 재 렌더링하게 됩니다. 그러면 이벤트에 의해 IsModalOpen이 true가 되었기 때문에 재 렌더링 시 if문의 분기를 통과해서 모달창이 표시되게 됩니다.

IsModalOpen 프로퍼티에는 값이 변경되었을 때 재랜더링을 요청하는 부분이 없습니다.
razor 가 아닌 일반 cs파일의 프로퍼티인데도 razor에서 사용되기만하면 추적되어 재랜더링되는건가요?

Razor에서 이벤트 발생시 재랜더링이 됩니다.


제가 핸드폰으로 답변을 달아 제대로 답변을 달지 못한 것 같습니다. 시간될 때 위의 코드를 참고해서 테스트해본 후 정확한 답변 드리도록 하겠습니다.

제시한 코드로 테스트를 한 후 테스트한 결과를 공유 드립니다.

  • EventCallback을 파라미터로 해서 설정될 경우 재 랜더링 시 해당 컴포넌트도 랜더링 대상이 됩니다.
    만약 Board.razor가 재 랜더링 된다 하더라도 속해있는 모든 컴포넌트들이 재 랜더링되는 것은 아니며 파라미터 전달 값이 달라질 경우에만 속해있는 컴포넌트에게 재 랜더링할 것을 요청합니다.
    예를들어 IsOpenChanged 속성을 제거했을 경우 Board가 재랜더링 되더라도 Model이 랜더링 되지 않습니다.

  • EventCallback이 아닌 값 파마리터도 마찬가지인가요?
    예 맞습니다. 하지만 동일 값이 전달될 경우에는 재 랜더링하지 않습니다. 파라미터의 값이 변경될 때만 해당 컴포넌트가 재 랜더링 됩니다.

  • 그런데 EventCallback은 전달된 람다 또는 함수가 심지어 실행되지 않는데도 불구하고 계속해서 재 랜더링 대상이 되나요?
    저도 정확히는 모르겠지만 아마도 재 랜더링 시 Blazor에서 최적화의 일환으로 컴포넌트에 전달하는 파라미터의 해시값에 의해 컴포넌트가 변경되었음을 (재 랜더링해야 함을) 감지하는 것 같습니다. 정확하게는 EventCallback의 해시값이 어떠한지를 살펴봐야겠습니다.

1 Like

IsModalOpen 값이 변경될 때
StateHasChanged()를 한번 넣어보시겠어요?
값이 변경되어 렌더링 요청을 다시 하는 메서드인데
보통은 @dimohy 님께서 말씀하신 것 처럼 자동으로 실행되지만 강제로 호출하는 방법이 있어요.

1 Like