Component lifecycle in blazor

The component lifecycle in Blazor defines a sequence of methods that are executed as a component is initialized, rendered, updated, and disposed. Understanding these lifecycle methods helps you manage data, handle events, and optimize performance in your Blazor applications.

Key Lifecycle Methods

1️⃣ OnInitialized (or OnInitializedAsync)

  • Purpose: Called when the component is initialized. Use this to set up component state or initiate long-running operations (e.g., API calls).

  • Async Version: Use OnInitializedAsync if the initialization logic is asynchronous.

  • Called Once: Only invoked the first time the component is rendered.

razorCopyEdit@code {
    protected override void OnInitialized()
    {
        // Synchronous initialization
        Console.WriteLine("Component initialized");
    }

    protected override async Task OnInitializedAsync()
    {
        // Asynchronous initialization
        await Task.Delay(1000);
        Console.WriteLine("Component initialized asynchronously");
    }
}

2️⃣ OnParametersSet (or OnParametersSetAsync)

  • Purpose: Called whenever the component's parameters are set or updated.

  • Async Version: Use OnParametersSetAsync if the parameter logic is asynchronous.

  • Called Multiple Times: Invoked after OnInitialized and every time the parent component passes new parameters to this component.

razorCopyEdit@code {
    [Parameter] public string Name { get; set; }

    protected override void OnParametersSet()
    {
        Console.WriteLine($"Parameters set: {Name}");
    }

    protected override async Task OnParametersSetAsync()
    {
        await Task.Delay(500);
        Console.WriteLine($"Parameters set asynchronously: {Name}");
    }
}

3️⃣ OnAfterRender (or OnAfterRenderAsync)

  • Purpose: Invoked after the component has finished rendering. Use this to interact with the DOM or run JavaScript.

  • Async Version: Use OnAfterRenderAsync for asynchronous tasks.

  • Executed Once (Initial Render): The firstRender parameter is true on the initial render and false for subsequent renders.

  • Avoid Triggering Rerenders: Do not update the component's state directly here as it can cause an infinite render loop.

razorCopyEdit@code {
    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            Console.WriteLine("First render completed");
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await Task.Delay(500);
            Console.WriteLine("First render completed asynchronously");
        }
    }
}

4️⃣ ShouldRender

  • Purpose: Controls whether the component should render. Returning false skips the render process.

  • Default: If not overridden, the default behavior is to always render (true).

  • Optimization: Use this for performance optimizations when the render is unnecessary.

razorCopyEdit@code {
    private bool shouldRender = true;

    protected override bool ShouldRender()
    {
        return shouldRender; // Only render when `shouldRender` is true
    }

    public void TriggerRender()
    {
        shouldRender = true;
        StateHasChanged(); // Manually trigger render
    }
}

5️⃣ Dispose (or IAsyncDisposable.DisposeAsync)

  • Purpose: Used to release resources (e.g., event handlers, timers, streams) when the component is removed from the UI.

  • Async Version: Implement IAsyncDisposable for asynchronous cleanup.

razorCopyEdit@implements IDisposable

@code {
    private Timer timer;

    protected override void OnInitialized()
    {
        timer = new Timer(OnTimerTick, null, 0, 1000);
    }

    private void OnTimerTick(object state)
    {
        Console.WriteLine("Timer tick");
    }

    public void Dispose()
    {
        timer?.Dispose();
        Console.WriteLine("Component disposed");
    }
}

Lifecycle Sequence

  1. Component Initialization

    • OnInitializedOnInitializedAsync
  2. Parameter Updates

    • OnParametersSetOnParametersSetAsync
  3. Render Phase

    • ShouldRender

    • Render Happens

    • OnAfterRenderOnAfterRenderAsync

  4. Component Destruction

    • Dispose (or DisposeAsync)

Visual Representation

plaintextCopyEdit1. Component Initialization
   - OnInitialized / OnInitializedAsync
   - OnParametersSet / OnParametersSetAsync

2. Render Phase
   - ShouldRender
   - Render UI
   - OnAfterRender / OnAfterRenderAsync

3. State Update (e.g., Parent Parameter Change or Event Trigger)
   - OnParametersSet / OnParametersSetAsync
   - ShouldRender
   - Render UI
   - OnAfterRender / OnAfterRenderAsync

4. Component Disposal
   - Dispose / DisposeAsync

Best Practices

  1. Use OnInitialized for initial state setup.

  2. Avoid heavy logic in OnAfterRender unless interacting with JavaScript or DOM.

  3. Use ShouldRender to improve performance for components that don't need frequent rerenders.

  4. Always dispose of resources in Dispose to prevent memory leaks.

  5. Use StateHasChanged cautiously to avoid unnecessary renders.