What happens when you navigate to the same page in Blazor?

Published on

Sometimes you might want the same ‘page’ in your Blazor app to load for different paths.

Here’s an example of a contacts page that loads the same component for both /contacts and /contacts/{id}

When the user clicks the link to view the ‘Alice Krige’ contact the browser will attempt to navigate to /contacts/1.

However, Blazor will intercept this navigation and, rather then reload the entire site, simply re-render this same component with the new parameter values.

Because the Id parameter is set to 1 the details for user 1 will be shown instead of the list of contacts.

Although you can’t see the navigation changes occurring in this demo, here’s the page in action:

Depending on which browser you’re using, if you hover over the links you should see the URL they’re pointing at.

If you want to see the page complete with navigation changes, you can view it here. As you interact with it notice how the URL changes between /contacts and /contacts/1.

What’s happening?

Blazor intercepts all attempts to navigate ‘within’ your app.

In practice this means, rather than dive off to a server to locate a page given a URL, Blazor will instead inspect the path you’re attempting to navigate to and determine which components need to be rendered.

In this case this one component is configured to handle two paths, with or without the contact id.

@page "/contacts/"
@page "/contacts/{id:int}"

When we click on a link which ends up at this same component, Blazor figures the component is already initialized and so rather than re-initialize it, re-renders it with the new parameters.

I’ve included some logging in the example for these lifecycle events:

When we first hit this page, if we inspect the console (in the browser), we can see these events logged.

After that though, when we navigate to the details for “Alice Krige” we see only these events logged:

Notice that the component is not re-initialized.

This matters because, if you attempt to perform important work, like fetching data, in the OnInitialized method, you’re going to be disappointed when you navigate around and find that data isn’t loading!

The answer? Move that work to the OnParametersSet method instead.

protected override void OnParametersSet()
{
// need logic to run every time you navigate to this component? Put it here.
base.OnParametersSet();
}

Here you can fetch any data you like, confident that this method will always be invoked when navigation events bring the user to this component (whether they’re coming here from the “same” component, or a different one entirely).

Watch out for over eager data fetching

If you want to be a little more circumspect about when to perform actions in OnParameterSet, you can implement your own check to see if a relevant parameter has changed.

For example, you might want to fetch contact details, but only if the Id parameter has changed.

Here’s one way of implementing that check…

int? previousId;
protected override void OnParametersSet()
{
if (Id.HasValue && Id != previousId)
{
// fetch contact details
Console.WriteLine("Fetching contact details");
previousId = Id;
}
base.OnParametersSet();
}

Here we check if we have a value in previousId and whether it matches the current value for our Id parameter.

If the incoming Id and previousId values differ we can go ahead and fetch the contact details.

We also need to remember to update the value of previousId so we can perform this same check again next time.

Are you getting the most out of Blazor?

Make more of Blazor's component model, and build modern, reliable web applications, faster with .NET.

Speed up your development
Next Up
  1. Need your Blazor sibling components to talk to each other?
  2. State Hasn't Changed? Why and when Blazor components re-render
  3. Your Blazor component needs data in a certain format, where to Map?