Lessons in this course (9)

7. Blazor components — parameters, events, child content and generics

Intermediate★ Must knowLesson 7 of 9
razor
@* Components/ConfirmButton.razor *@
<button class="btn @CssClass" @onclick="AskAsync" disabled="@_busy">@ChildContent</button>
@if (_asking)
{
    <div class="confirm">
        <span>@Message</span>
        <button @onclick="() => ConfirmAsync(true)">Yes</button>
        <button @onclick="() => ConfirmAsync(false)">No</button>
    </div>
}

@code {
    [Parameter] public string Message { get; set; } = "Are you sure?";
    [Parameter] public string CssClass { get; set; } = "btn-danger";
    [Parameter] public RenderFragment? ChildContent { get; set; }          // content between the tags
    [Parameter] public EventCallback OnConfirmed { get; set; }             // event to the parent
    private bool _asking, _busy;

    private void AskAsync() => _asking = true;
    private async Task ConfirmAsync(bool yes)
    {
        _asking = false;
        if (!yes) return;
        _busy = true;
        await OnConfirmed.InvokeAsync();                                   // parent's handler runs, UI re-renders
        _busy = false;
    }
}
razor
<ConfirmButton Message="Delete this order?" OnConfirmed="DeleteOrderAsync">Delete</ConfirmButton>
razor
@* Generic, templated component *@
@typeparam TItem
<table class="table">
    <thead><tr>@Header</tr></thead>
    <tbody>@foreach (var item in Items) { <tr>@Row(item)</tr> }</tbody>
</table>
@code {
    [Parameter, EditorRequired] public IReadOnlyList<TItem> Items { get; set; } = [];
    [Parameter] public RenderFragment? Header { get; set; }
    [Parameter, EditorRequired] public RenderFragment<TItem> Row { get; set; } = default!;
}

Key concepts: lifecycle (OnInitialized(Async), OnParametersSet(Async), OnAfterRender(Async), Dispose), StateHasChanged(), @bind / @bind-Value two-way binding (Value + ValueChanged parameters), CascadingValue/[CascadingParameter] for shared context (theme, auth state), @key for list diffing, render modes in .NET 8+ (Static SSR, InteractiveServer, InteractiveWebAssembly, InteractiveAuto), JS interop (IJSRuntime), CSS isolation (Component.razor.css).