Reputation: 49
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 intoOnAfterRender
orOnAfterRenderAsync
.
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:
Upvotes: 1
Views: 814
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