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 called twice.
In the Index.razor page I have this code:
@code{
protected async override Task OnInitializedAsync()
{
UriHelper.NavigateTo("/counter");
}
}
Then in the counter page I added the following code with a breakpoint in it:
protected override void OnInitialized()
{
}
My expectation is to call the counter page only one time when the NavigateTo calls the counter route in the Index.razor
By using Blazor route parameters, you can pass values from one page to another page. Use NavigationManager to pass a value and route the parameter to another page. Follow this example to achieve passing values from one page to another. Get the passed Page1 parameter value in Page2.
Inject NavigationManager in razor. Use Uri from NavigationManager to get the current URL.
Razor components are units of markup and code that represent the basic UI elements of any Blazor app implemented with a . razor extension. In other words, Blazor uses Razor components to create UIs, meaning you can write Razor components and utilize Blazor as the client-side hosting model for them.
You can redirect to a page in Blazor using the Navigation Manager's NavigateTo method. In the following code snippet, it will redirect to the home page when this page gets loaded. Similarly, you can call NavigateTo() method from NavigationManager class anywhere to redirect to another page.
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:
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.
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With