防止 StateHasChanged 的 Blazor 级联组件
Blazor cascading component preventing StateHasChanged
所以我是 Blazor 的新手,我刚刚发现了 CascadingValue 及其用于显示错误消息的可能用途。我正在创建一个 Outlook 加载项以在 Sharepoint 中保存邮件和附件,因此我使用 Office-js 和 JSInterop 动态检索当前的 Outlook 邮件,这样我的加载项始终使用选定的邮件。
但现在我正在尝试为错误消息实现级联组件,我 运行 遇到了 StateHasChanged 问题。
以下代码是我的级联错误组件:
<CascadingValue Value=this>
@ChildContent
</CascadingValue>
<div class="error-container @(ErrorMessage == null ? "hidden" : "")">
<span class="error-message">
@ErrorMessage
</span>
<a class="dismiss-error" @onclick="DismissError">x</a>
</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public string ErrorMessage { get; set; }
public void ProcessError(Exception ex)
{
ErrorMessage = ex.Message;
StateHasChanged();
}
public void DismissError()
{
ErrorMessage = null;
StateHasChanged();
}
}
我遇到问题的组件(至少是重要部分):
<div>
{Showing details from OutlookMail here}
</div>
@code {
[CascadingParameter] public Error Error { get; set; }
public OutlookMail OutlookMail { get; set; }
private static Action<OutlookMail> _receiveMailAction;
protected override async Task OnInitializedAsync()
{
_receiveMailAction = UpdateMail;
await base.OnInitializedAsync();
}
private void UpdateMail(OutlookMail mail)
{
InvokeAsync(() =>
{
OutlookMail = mail;
StateHasChanged();
});
}
[JSInvokable]
public static void ReceiveMail(OutlookMail mail)
{
_receiveMailAction?.Invoke(mail);
}
public async Task MethodWithError()
{
try
{
await DoStuffWithPossibleError();
}
catch (Exception e)
{
Error.ProcessError(e);
}
}
}
一切正常,直到 Error.ProcessError 被调用并显示错误消息,之后 StateHasChanged 停止重新呈现我的组件,这给用户提供了不一致的数据。
我可能做错了什么,因为我真的找不到其他有同样问题的人,但我没有看到它,所以我希望这里的人能更好地了解问题所在出错了,或者如果问题出在像这样使用 CascadingValue 上,甚至可能是显示错误消息的更好方法。
感谢所有帮助。
编辑 1:在进一步研究之后,似乎它实际上并没有更新 OutlookMail,即使我将它移出 InvokeAsync 也是如此。所以我的组件实例可能会发生一些奇怪的事情
在我第一次编辑之后,我发现它确实是实例的问题,因为我在 OnInitialized 中覆盖了一个静态操作,每次它创建一个新实例时,旧实例不再有效。并且返回错误的代码恰好有一个带有重定向回调到同一页面的身份验证对话框,它在之后直接关闭,但加载页面实际上创建了我的组件的一个新实例,这反过来使我的用户使用的那个无效.所以我可能只需要创建一个处理传入邮件数据的单例服务,这样我的组件就可以始终访问正确的数据。
所以我是 Blazor 的新手,我刚刚发现了 CascadingValue 及其用于显示错误消息的可能用途。我正在创建一个 Outlook 加载项以在 Sharepoint 中保存邮件和附件,因此我使用 Office-js 和 JSInterop 动态检索当前的 Outlook 邮件,这样我的加载项始终使用选定的邮件。 但现在我正在尝试为错误消息实现级联组件,我 运行 遇到了 StateHasChanged 问题。
以下代码是我的级联错误组件:
<CascadingValue Value=this>
@ChildContent
</CascadingValue>
<div class="error-container @(ErrorMessage == null ? "hidden" : "")">
<span class="error-message">
@ErrorMessage
</span>
<a class="dismiss-error" @onclick="DismissError">x</a>
</div>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public string ErrorMessage { get; set; }
public void ProcessError(Exception ex)
{
ErrorMessage = ex.Message;
StateHasChanged();
}
public void DismissError()
{
ErrorMessage = null;
StateHasChanged();
}
}
我遇到问题的组件(至少是重要部分):
<div>
{Showing details from OutlookMail here}
</div>
@code {
[CascadingParameter] public Error Error { get; set; }
public OutlookMail OutlookMail { get; set; }
private static Action<OutlookMail> _receiveMailAction;
protected override async Task OnInitializedAsync()
{
_receiveMailAction = UpdateMail;
await base.OnInitializedAsync();
}
private void UpdateMail(OutlookMail mail)
{
InvokeAsync(() =>
{
OutlookMail = mail;
StateHasChanged();
});
}
[JSInvokable]
public static void ReceiveMail(OutlookMail mail)
{
_receiveMailAction?.Invoke(mail);
}
public async Task MethodWithError()
{
try
{
await DoStuffWithPossibleError();
}
catch (Exception e)
{
Error.ProcessError(e);
}
}
}
一切正常,直到 Error.ProcessError 被调用并显示错误消息,之后 StateHasChanged 停止重新呈现我的组件,这给用户提供了不一致的数据。
我可能做错了什么,因为我真的找不到其他有同样问题的人,但我没有看到它,所以我希望这里的人能更好地了解问题所在出错了,或者如果问题出在像这样使用 CascadingValue 上,甚至可能是显示错误消息的更好方法。
感谢所有帮助。
编辑 1:在进一步研究之后,似乎它实际上并没有更新 OutlookMail,即使我将它移出 InvokeAsync 也是如此。所以我的组件实例可能会发生一些奇怪的事情
在我第一次编辑之后,我发现它确实是实例的问题,因为我在 OnInitialized 中覆盖了一个静态操作,每次它创建一个新实例时,旧实例不再有效。并且返回错误的代码恰好有一个带有重定向回调到同一页面的身份验证对话框,它在之后直接关闭,但加载页面实际上创建了我的组件的一个新实例,这反过来使我的用户使用的那个无效.所以我可能只需要创建一个处理传入邮件数据的单例服务,这样我的组件就可以始终访问正确的数据。