VitalySky
VitalySky

Reputation: 1

Blazor: OnInitialized called after a component rerenders

My colleagues and me faced the problem that a blazor component (we call it View) is recreated when a root component's StateHasChanged is called. So, at that moment the View's OnInitialized method is executed. If I understend it right, OnInitialized method is only executed once when the component is first created. But our View component had been already created and it is stored in a private field of stack type.

The code from .razor file (root component):

@foreach (var rec in _navStack)
{
    <div class = "viewport" style = "height : calc(100vh - 104px)">
        <div @key="rec.Id" class="h-100 @(rec == _navStack.Peek() ? "d-block" : "d-none")">
            @rec.Fragment
        </div>
    </div>
}

The problem View is stored in _navStack. When user clicks some button, root component's StateHasChanged method is called and then foreach block is executed. And when rec.Fragment (View) is rendered, View's OnInitialized method is executed. This situation causes some problems that require more details, but it is not important now.

Interesting fact - if we move <div class = "viewport"...> block outside foreach block everything works just fine!

<div class = "viewport" style = "height : calc(100vh - 104px)">
@foreach (var rec in _navStack)
{
    <div @key="rec.Id" class="h-100 @(rec == _navStack.Peek() ? "d-block" : "d-none")">
        @rec.Fragment
    </div>
}
</div>

css styles:

.viewport {
    min-height: 100%;
    padding: 0 10px;
    overflow: clip;
}
.d-block {
  display: block !important;
}
.d-none {
  display: none !important;
}

Any guess?

Upvotes: 0

Views: 50

Answers (1)

MrC aka Shaun Curtis
MrC aka Shaun Curtis

Reputation: 30320

This question is probably impossible to answer without a miminal working example to demonstrate it.

Fact: OnInitialized{Async} is run only once in a component's lifecycle [unless you call it manually].

So, somewhere in your code, you are re-creating the component.

Your can do something like this to provide it:


@code {
    private Guid _componentId = Guid.NewGuid();

    // CTOR
    public Home()
    {
        Console.WriteLine($"Someone Createe me.  My Id is: {_componentId}");
    }

    protected override void OnInitialized()
    {
        Console.WriteLine($"OnInitialized called on ComponentId: {_componentId}");
    }
}

How to solve it: No idea without a miminal working example.

Upvotes: 0

Related Questions