Search code examples
c#blazorblazor-server-side

Why is OnInitialized triggered when using NavigationManager to navigate to the same page


This is in a Blazor Server App with per page interactivity.

In my search page, I want to update the page url when the parameter changes, so the link can be copied. My understanding was that by using the NavigationManager Blazor would detect no full reload is needed, and skip component initialization.

The reason I want this, is so filter settings etc. do not get reset every time. The other options I have are saving filter settings in state, or updating the URL with JS Interop by calling history.pushState.

I would expect the following code not to hit OnInitialized() after Start search is clicked.

@page "/test/{searchvalue}"
@rendermode InteractiveServer
@inject NavigationManager _NavigationManager

<InputText @bind-Value="SearchInput"></InputText>
<div @onclick="(() => Search())">Start search</div>

<br />
<br />

Test input: @SearchValue

@code{

    [Parameter]
    public string SearchValue { get; set; } = "";

    public string SearchInput { get; set; } = "";

    protected override void OnInitialized()
    {
        // Inital filter settings etc.
        // ...

        base.OnInitialized();
    }

    protected override void OnParametersSet()
    {
        if (SearchInput != SearchValue)
        {
            SearchInput = SearchValue;

            // Do the actual searching ...
        }
    }

    protected void Search()
    {
        _NavigationManager.NavigateTo($"/test/{SearchInput}", false, false);
    }
}

Solution

  • This issue is mainly related with static routing,as mentioned in the document:

    When an interactive render mode is assigned to the Routes component, the Blazor router becomes interactive after static SSR with static routing on the server. This type of routing is called interactive routing.

    Static routers use endpoint routing and the HTTP request path to determine which component to render. When the router becomes interactive, it uses the document's URL (the URL in the browser's address bar) to determine which component to render. This means that the interactive router can dynamically change which component is rendered if the document's URL dynamically changes to another valid internal URL, and it can do so without performing an HTTP request to fetch new page content.

    you didn't assign interactiveserver render mode to routes component in app.razor

    <Routes @rendermode="InteractiveServer" />
    

    for you set interactive server render mode per component, so your app is always in static routing.

    I created a blazor server app which interactive location is gobal, OnInitialized() would not be hit on my side when navigate to itself