Blazor UriHelper.NavigateTo is calling the page twice

前端 未结 2 1635
无人及你
无人及你 2020-12-18 09:26

I created a new Blazor Server Side Application in Preview 8. When I call the UriHelper.NavigateTo to go to the counter page from the Index.razor page, the counter page is c

相关标签:
2条回答
  • 2020-12-18 09:52

    Update due to a comment by dani herrera:

    The life cycle method OnInitializedAsync is called twice, but the counter @page component is called once only. This behavior is by design. The first time OnInitializedAsync is executed is when server-side Blazor app is being pre-rendering, during which time, JSInterop is not available, and thus calling UriHelper.NavigateTo("/counter"); triggers an error. The following code snippet describe how Blazor currently treats such cases:

    protected override void NavigateToCore(string uri, bool forceLoad)
            {
                Log.RequestingNavigation(_logger, uri, forceLoad);
    
                if (_jsRuntime == null)
                {
                    var absoluteUriString = ToAbsoluteUri(uri).ToString();
                    throw new NavigationException(absoluteUriString);
                }
    
                _jsRuntime.InvokeAsync<object>(Interop.NavigateTo, uri, forceLoad);
            }
    

    See more here. As you may realize, the counter @page component is not called, and an exception is raised.

    After pre-rendering has completed, client-side SignalR establishes a connection to the server, and your app is rendered. This time (second time the method OnInitializedAsync is called) UriHelper.NavigateTo("/counter"); is properly executed, and we are happily navigated to the counter page (first time)

    You may use the method OnAfterRender as a workaround, and you should verify whether a connection with the server has already been established by SignalR; that is the pre-rendering process has completed.

    @page "/"
    @using Microsoft.JSInterop
    @inject IComponentContext ComponentContext
    @inject IJSRuntime jsRuntime
    
    <p>Navigate to the counter component.</p>
    
    @code{
    
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (!ComponentContext.IsConnected) return;
    
             UriHelper.NavigateTo("/counter");
        }
    }
    

    Hope this helps...

    0 讨论(0)
  • 2020-12-18 09:56

    This behavior is because the pre-render feature. Notice that, when you are on counter page (loaded for twice), if you click on Home, only one execution is fired:

    Summarizing:

    When pre-render is enabled (by default), the prerended page's OnInitializedAsync is called for twice by design. For this reason, your redirect statement is executed for twice.

    To test is I wrote this code on index OnInitializedAsync:

    @page "/"
    @inject IUriHelper UriHelper
    
    <h1>Hello, world!</h1>
    
    Welcome to your new app.
    
    @code{
    
        protected async override Task OnInitializedAsync()
        {
            System.Console.WriteLine("_*   ");
            System.Console.WriteLine("_**************************");
            System.Console.WriteLine("_***** Pre render ******");
            System.Console.WriteLine("_**************************");
            System.Console.WriteLine("_   ");
            return;
        }
    }
    

    And I call the page using pre-render and from the app (without prerender). Noticed that when I force reload (prerended) the OnInitializedAsync is executed for twice:

    Learn more about render modes.

    0 讨论(0)
提交回复
热议问题