freeliner
freeliner

Reputation: 49

Fetching Data in Blazor ComponentBase class

Each Blazor component has a method OnInitializedAsync() which can be overriden. It seems to be a good place for any calls to fetch data which should be used during component render, like:

protected override async Task OnInitializedAsync()
{
    var dataForRendering = await SomeHttpClient.RetrieveSomeData();
}

However, there is a known behavior in Blazor components where the OnInitializedAsync() method is fired twice. There is a description on how to handle it, in the Stackoverflow discussion.

The recommendation there was to check on the ComponentContext.IsConnected state which allows to fire required operations only once.

However, an update from September, 4th tells that we should

Remove any usage of IComponentContext and move any logic that should not run during prerendering into OnAfterRender or OnAfterRenderAsync.

Using OnAfterRenderAsync instead is not an option here as well. Yes, it is being fired only once, but by the time it is fired, the component is already rendered and it is late to retrieve any data which should be used for rendering.

So the question is:

  1. How to avoid double-loading of data during 'OnInitializedAsync()' execution now? Twice the calls to the data server is not a good performance example.
  2. Is it a good idea to load data for a component render like that at all? Maybe there are better ways to pass data to a component?

Upvotes: 1

Views: 814

Answers (1)

enet
enet

Reputation: 45586

The OnInitialized(Async) pairs are executed twice if you use Blazor Server App, and pre-rendering is enabled. To disable pre-rendering you should set the attribute render-mode of the component element in the _Host.cshtml file to "Server"

<app>
    <component type="typeof(App)" render-mode="Server" />
</app>

This disable the pre-rendering feature. No pre-rendering, no second execution of code.

Is it a good idea to load data for a component render like that at all? Maybe there are better ways to pass data to a component?

The way to initialize a component with data is to use the OnInitialized(Async) pairs...

The OnAfterRender(Async) pairs are not appropriate for that purpose, though it may seem to render fine on a small scale data load. They are most appropriately used to initizlise JavaScript compoenets, after Blazor components have been rendered.

Hope this helps...

Upvotes: 1

Related Questions