Жизненный цикл компонента Blazor

Компоненты Blazor имеют четко определенный жизненный цикл. Жизненный цикл компонента можно использовать для инициализации состояния компонента и/или реализации расширенного поведения компонентов. Компонент обрабатывает события своего жизненного цикла в наборе синхронных и асинхронных методов. Эти методы, при желании, можно переопределить для выполнения дополнительных операций с компонентом.

Методы жизненного цикла компонентов Blazor

OnInitialized

Методы OnInitialized и OnInitializedAsync используются для инициализации компонента. Обычно компонент инициализируется после первого рендеринга. После того, как компонент инициализирован, он может быть отрендерен несколько раз, прежде чем в конечном итоге будет уничтожен. 
protected override void OnInitialized() { ... }
protected override async Task OnInitializedAsync() { await ... }

Например, у нас в приложении используется компонент, который выводит на экран сведения о человеке:

@page "/view-person"

@using MyApp.Data;

<h3>Person</h3>

<p>Имя: @person.Name</p>
<p>Возраст: @person.Age</p>
<p>Пол: @person.Gender</p>

@code {
    Person person;
}

При попытке обращения к такому компоненту мы неизбежно получим исключение:

System.NullReferenceException: «Object reference not set to an instance of an object.»
person было null.

В данном случае, мы могли бы поступить, например, так:

@code {
    Person person = new() { Name = "Вася Пупкин", Age = 18, Gender = "Мужской" };
}

то есть сразу создать и инициализировать объект типа Person какими-то значениями по умолчанию. Это самый простой случай. Но, возможно, что по логике нашего приложения мы должны инициализировать объект, например, данными из базы данных. В этом случае как раз было бы удобным использовать метод OnInitialized (или его асинхронную версию OnInitializedAsync). В нашем примере это можно было бы сделать, переопределив метод:

@page "/view-person"

@using MyApp.Data;

<h3>Person</h3>

<p>Имя: @person.Name</p>
<p>Возраст: @person.Age</p>
<p>Пол: @person.Gender</p>

@code {
    Person person;

    protected override void OnInitialized()
    {
        person = new()
            {
                Name = "Вася Пупкин",
                Age = 18,
                Gender = "Мужской"
            };
    }
}

OnParametersSet

Методы OnParametersSet и OnParametersSetAsync вызываются, когда компонент получает значения параметров от своего родителя и значение присваивается свойствам. Эти методы выполняются после инициализации компонента и при каждом рендеринге компонента.

protected override void OnParametersSet() { ... }
protected override async Task OnParametersSetAsync() { await ... }

Эти методы выполняются также и в том случае, если родительский компонент не передает никаких параметров компоненту. Проверить это легко, если переопределить в нашем компоненте метод OnParametersSet следующим образом:

protected override void OnParametersSet()
{
    Console.WriteLine("OnParametersSet()");
}

запустить приложение Blazor Server и загрузить компонент. В консоли мы увидим, что метод OnParametersSet был выполнен, несмотря на то, что мы не передавали этому компоненту никаких параметров:

В этом методе мы можем проводить какие-либо дополнительные манипуляции с переданными данными. Например, родительский компонент в качестве параметра может передать id элемента в базе данных, а в методе OnParametersSet нашего компонента мы можем получить данные из БД.

OnAfterRender

Методы OnAfterRender и OnAfterRenderAsync вызываются после завершения визуализации компонента. На этом этапе заполняются ссылки на элементы и компоненты.  При выполнении этого метода пользователь может выполнять какие-либо действия в браузере. Методы OnAfterRender и OnAfterRenderAsync не вызываются при предварительном рендеринге на сервере. Параметр firstRender имеет значение true при первом рендеринге компонента, в противном случае его значение равно false.

protected override void OnAfterRender(bool firstRender)
{
 if (firstRender)
{
 ...
}
}

protected override async Task OnAfterRenderAsync(bool firstRender)
{
 if (firstRender)
 {
 await ...
 }
}

Чтобы продемонстрировать когда параметр firstRender меняет свое значение с true на false допишем наш компонент следующим образом:

@page "/view-person"

@using MyApp.Data;

<h3>Person</h3>
<p>Имя: @person.Name</p>
<p>Возраст: @person.Age</p>
<p>Пол: @person.Gender</p>

<button @onclick="OnClick">Изменить Person</button>


@code {
    Person person = new()
        {
            Name = "Вася Пупкин",
            Age = 18,
            Gender = "Мужской"
        };

    private void OnClick()
    {
        person.Name = "Петя";
        person.Age = 15;
        person.Gender = "мужской";
    }

    protected override void OnInitialized()
    {

        Console.WriteLine("OnInitialized()");
    }

    protected override void OnParametersSet()
    {
        Console.WriteLine("OnParametersSet()");
    }

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
            Console.WriteLine("OnAfterRender(firstRender = true)");
        else
            Console.WriteLine("OnAfterRender(firstRender = false)");
    }
}

Здесь мы добавили кнопку клик по которой приводит к изменению значений свойств объекта person. Теперь можно запустить приложение, перейти к компоненту и увидеть следующий вывод в консоли:

OnInitialized()
OnParametersSet()
OnAfterRender(firstRender = true)

Если мы просто обновим страницу в браузере, то вывод консоли не изменится — firstRender также будет равен true, однако, если мы нажмем на кнопку несколько раз, то получим уже следующий вывод консоли:

OnInitialized() OnParametersSet()
OnAfterRender(firstRender = true)
OnAfterRender(firstRender = false)
OnAfterRender(firstRender = false)
OnAfterRender(firstRender = false)
OnAfterRender(firstRender = false)

в данном случае, кнопка была нажата четыре раза — компонент был перерисован также четырежды.

Интерфейс IDisposable

Компоненты Blazor могут реализовать интерфейс IDisposable для удаления ресурсов, когда компонент удален из пользовательского интерфейса. Для этого необходимо воспользоваться директивой @implements, например так:

@page "/view-person"

@using MyApp.Data;

@implements IDisposable;

.....

@code {
.....
    public void Dispose()
    {
        Console.WriteLine("Dispose()");
    }
}

Итого

Компоненты Blazor имеют четко определенный жизненный цикл, воздействовать на который мы можем переопределением методов жизненного цикла и реализацией интерфейса IDisposable. Порядок выполнение методов от инициализации компонента до его удаления из интерфейса следующий: OnInitialized() —> OnParametersSet() —> OnAfterRender(firstRender = true) —> OnAfterRender(firstRender = false) —> ….. OnAfterRender(firstRender = false) —> Dispose().

Подписаться
Уведомить о
guest
1 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии