Blazor Lifecycle Demo

Parent Value: 0

*Lưu ý: Khi child component bị unmount thì sẽ gọi đến Dispose (nếu có) → có thể dùng để cleanup resource, hủy subscription,...*

Child Value: 0(EnableFilter: False)

Child Logs:

    Xem code
    Parent page(LifecycleDemo.razor)
    @page "/lifecycle-demo"
            <div class="border rounded p-3">
            @*Cài đặt tham số cho LifeCycle của child Component*@
            <div class="form-check ms-2">
                <input class="form-check-input" type="checkbox" id="chkOI" @bind="_useAwaitInChild_OnInitializedAsync"/>
                <label class="form-check-label" for="chkOI">Chạy Await trong hàm OnInitializedAsync của Child Component</label>
            </div>
            
            <div class="form-check ms-2">
                <input class="form-check-input" type="checkbox" id="chkOP" @bind="_useAwaitInChild_OnParametersSetAsync"/>
                <label class="form-check-label" for="chkOP">Chạy Await trong hàm OnParametersSetAsync của Child Component</label>
            </div>
    
            <div class="form-check ms-2">
                <input class="form-check-input" type="checkbox" id="chkOA" @bind="_useAwaitInChild_OnAfterRenderAsync"/>
                <label class="form-check-label" for="chkOA">Chạy Await trong hàm OnAfterRenderAsync của Child Component</label>
            </div>
    
            <div class="form-check ms-2">
                <input class="form-check-input" type="checkbox" id="chkES" @bind="_enableChildShouldRenderFilter"/>
                <label class="form-check-label" for="chkES">Bật bộ lọc ShouldRender của Child Component</label>
            </div>
    
             @*Tham số truyền vào child component*@
            <div class="d-flex align-items-center gap-2 flex-wrap">
                <button class="btn btn-primary" @onclick="Inc">Value++</button>
                <button class="btn btn-outline-secondary" @onclick="ToggleChild">Toggle Child (mount/unmount)</button>
            </div>
            <p class="mt-3 mb-2"><b>Parent Value:</b> @_value</p>
            </div>
            <span class="text-muted">*Lưu ý: Khi child component bị unmount thì sẽ gọi đến Dispose (nếu có) → có thể dùng để cleanup resource, hủy subscription,...*</span>
            <div class="border rounded p-3">
            @if (_showChild)
            {
                <div>
                    <LifecycleChild Value="@_value" EnableShouldRenderFilter="@_enableChildShouldRenderFilter" 
                    UseAwaitInOnInitializedAsync="@_useAwaitInChild_OnInitializedAsync" 
                    UseAwaitInOnParametersSetAsync="@_useAwaitInChild_OnParametersSetAsync" 
                    UseAwaitInOnAfterRenderAsync="@_useAwaitInChild_OnAfterRenderAsync"/>    
                </div>
                
            }
            else
            {
                <p class="text-muted mb-0">Child đang bị unmount → nếu trước đó có <code>Dispose</code> thì sẽ chạy.</p>
            }
            </div>
    
            @code{
                private bool _useAwaitInChild_OnInitializedAsync = false;
                private bool _useAwaitInChild_OnParametersSetAsync = true;   
                private bool _useAwaitInChild_OnAfterRenderAsync = false;
                private bool _enableChildShouldRenderFilter = false;
    
                private int _value = 0;
                private bool _showChild = true; 
    
                private void Inc()
                {
                    _value++;
                }
    
                private void ToggleChild()
                {
                    _showChild = !_showChild;
                }
            }
            
    Child Component (LifecycleChild.razor)
    @implements IDisposable
    
            <div class="border rounded p-3 bg-light">
                <p class="mb-1"><b>Child Value:</b> @Value<span class="text-muted">(EnableFilter: @EnableShouldRenderFilter)</span></p>
                <div>
                    <b>Child Logs:</b>
                    <ul class="mb-0">
                        @foreach (var line in _displayLogs)
                        {
                            <li>@line</li>
                        }
                    </ul>
                    <button class="btn btn-sm btn-outline-secondary mt-2" @onclick="() => _displayLogs = new List<string>(_logs)">Refresh Logs</button>
                    <button class="btn btn-sm btn-outline-secondary mt-2" @onclick="() => _clearLogsBeforeNextRender = true">Clear Logs</button>    
                </div>
            </div>
    
            @code
            {
                [Parameter] public int Value { get; set; }
                [Parameter] public bool UseAwaitInOnInitializedAsync { get; set; }
                [Parameter] public bool UseAwaitInOnParametersSetAsync { get; set; }
                [Parameter] public bool UseAwaitInOnAfterRenderAsync { get; set; }
    
                [Parameter] public bool EnableShouldRenderFilter { get; set; }
                private bool _clearLogsBeforeNextRender = false;
    
                private List<string> _logs = new();
                private List<string> _displayLogs = new();  
                private int _renderCount = 0;
    
                public override async Task SetParametersAsync(ParameterView parameters)
                {
                    Log("Child-SetParametersAsync() - start");
                    await base.SetParametersAsync(parameters);
                    Log("Child-SetParametersAsync() - end");
                }
    
                protected override void OnInitialized()
                {
                    Log("Child-OnInitialized()");
                }
    
                protected override async Task OnInitializedAsync()
                {
                    Log("Child-OnInitializedAsync() - start");
                    if (UseAwaitInOnInitializedAsync)
                    {
                        await Task.Delay(1);
                    }
                    Log("Child-OnInitializedAsync() - end");
                }
    
                protected override void OnParametersSet()
                {
                    Log($"Child-OnParametersSet() - Value={Value}");
                }
    
                protected override async Task OnParametersSetAsync()
                {
                    Log("Child-OnParametersSetAsync() - start");
                    if (UseAwaitInOnParametersSetAsync)
                    {
                        await Task.Delay(1);
                    }
                    Log("Child-OnParametersSetAsync() - end");
                }
    
                protected override bool ShouldRender()
                {
                    Log("Child-ShouldRender()");
                    if (!EnableShouldRenderFilter) 
                    {
                        return true;
                    }
                    return Value % 2 == 0; // chỉ render khi Value chẵn
                }
    
                protected override void OnAfterRender(bool firstRender)
                {
                    
                    Log($"Child-OnAfterRender(firstRender: {firstRender})");
                }
    
                protected override async Task OnAfterRenderAsync(bool firstRender)
                {
                    Log($"Child-OnAfterRenderAsync(firstRender: {firstRender}) - start");
                    if (UseAwaitInOnAfterRenderAsync)
                    {
                        await Task.Delay(1);
                    }
                    Log($"Child-OnAfterRenderAsync(firstRender: {firstRender}) - end");
    
                    if (_clearLogsBeforeNextRender)
                    {
                        _logs.Clear();
                        _displayLogs.Clear();
                        _clearLogsBeforeNextRender = false;
                    }
                }
    
                public void Dispose()
                {
                    Console.WriteLine($"Child-Dispose() {DateTime.Now:HH:mm:ss.fff}");
                }
    
                private void Log(string msg)
                    => _logs.Add($"{DateTime.Now:HH:mm:ss.fff} - {msg}");
            }
    
            

    An error has occurred. This application may no longer respond until reloaded. Reload 🗙
    Web hosting by Somee.com