Trying to pass down variabels with an AppState class, the components updates when the call happends in the same component but not in a childcomponent when the parrent triggers the event.
Parent
@code {
[Parameter]
public int Id { get; set; }
WikiDetailDto wikiDetail = null;
protected async override Task OnInitializedAsync()
{
Console.WriteLine("going in detail INIT");
AppState.OnCurrentWikiPageChanged = StateHasChanged;
AppState.SetCurrentWikiPage(await wikiPageService.GetDetail(Id));
wikiDetail = AppState.CurrentWikiPage;
Console.WriteLine("Retrieved WikiDetail!");
}
}
Child
<MudDrawer Anchor="Anchor.End" Open="true">
<MudDrawerHeader>Recommendations</MudDrawerHeader>
@if(AppState.CurrentWikiPage != null)
{
@(RecommendedWikiPages = CalculateReccomendedWikis(AppState.CurrentWikiPage));
if(RecommendedWikiPages != null)
{
foreach(var p in RecommendedWikiPages)
{
<MudCard>
<MudCardContent>
<MudText>@p.Name</MudText>
</MudCardContent>
</MudCard>
}
}
}
else
{
<p>Loading...</p>
}
When AppState.CurrentWikiPage gets updated, it doesn't check the if statement of the cild. What is best practice here? I don't want to use cascading values.
AppState
public WikiDetailDto CurrentWikiPage { get; set; }
public event Action OnCurrentWikiPageChanged;
public void SetCurrentWikiPage(WikiDetailDto wikiPage)
{
CurrentWikiPage = wikiPage;
OnCurrentWikiPageChanged?.Invoke();
}
CodePudding user response:
If I'm reading your code correctly, the child component needs to register for the OnCurrentWikiPageChanged
event.
Your child needs to look like this:
@implements IDisposable
..... markup code
protected async override Task OnInitializedAsync()
{
AppState.OnCurrentWikiPageChanged = StateHasChanged;
}
public void Dispose()
{
AppState.OnCurrentWikiPageChanged -= StateHasChanged;
}
Personally I would not link StateHasChanged
directly to the event handler. Its bad practice because StateHasChanged
has to run the the UI context thread. If the event caller is running on another thread, you'll get an exception. I would stick with a standard EventHandler
. WASM may be single threaded now, but it may not be forever.
My Handler would look something like:
private void OnxxxChanged(object sender, EventArgs e)
=> this.InvokeAsync(StateHasChanged);