Entenda o ciclo de vida do componente do Blazor

Concluído

Os componentes Blazor têm um ciclo de vida bem definido que começa quando eles são criados e termina quando são destruídos. O ciclo de vida do componente é regido por um conjunto de eventos que ocorrem em resposta a gatilhos específicos. Esses gatilhos incluem o componente sendo inicializado, os usuários interagindo com o componente ou a página em que o componente reside sendo fechada.

Nesta unidade, você conhece os eventos que ocorrem durante o ciclo de vida de um componente Blazor. Veja como lidar com esses eventos para otimizar o trabalho realizado e aumentar a capacidade de resposta de uma página Blazor.

O ciclo de vida do componente Blazor

Os componentes Blazor representam as exibições em aplicativos Blazor, definindo o layout e a lógica da interface do usuário. Os componentes geram a marcação HTML quando o aplicativo é executado. Os eventos de interação do usuário podem disparar código personalizado e os componentes podem ser atualizados para renderizar novamente a exibição. Após o fechamento da página, o Blazor remove o componente e limpa todos os recursos. Novas instâncias são criadas quando o usuário retorna à página.

O diagrama a seguir ilustra os eventos que ocorrem durante o tempo de vida de um componente e os métodos que você pode usar para lidar com esses eventos. O Blazor fornece versões síncronas e assíncronas de cada método, exceto de SetParametersAsync.

Todos os componentes Blazor descendem da classe ComponentBase ou IComponent que define os métodos mostrados e fornece o comportamento padrão. Você manipula um evento substituindo o método correspondente.

The Blazor component lifecycle.

Embora o diagrama indique que há um fluxo de thread único entre métodos de ciclo de vida, as versões assíncronas desses métodos permitem que um aplicativo do Blazor acelere o processo de renderização. Por exemplo, quando o primeiro await ocorre em SetParametersAsync, o componente Blazor executa os métodos OnInitialized e OnInitializedAsync. Quando a instrução aguardada for concluída, o thread de execução em SetParametersAsync será retomado.

A mesma lógica se aplica em toda a série de métodos de ciclo de vida. Além disso, cada operação await que ocorre durante OnInitializedAsync e OnParametersSetAsync indica que o estado do componente foi alterado e pode disparar uma renderização imediata da página. A página pode ser renderizada várias vezes antes da conclusão completa da inicialização.

Entender os métodos de ciclo de vida

Cada método de ciclo de vida de componente tem uma finalidade específica e você pode substituí-los para adicionar lógica personalizada ao componente. A tabela a seguir lista os métodos de ciclo de vida na ordem em que ocorrem e descreve sua finalidade.

Ordem Método de ciclo de vida Descrição
1 Componente criado O componente é instanciado.
2 SetParametersAsync Define parâmetros do pai do componente na árvore de renderização.
3 OnInitialized / OnInitializedAsync Ocorre quando o componente está pronto para ser iniciado.
4 OnParametersSet / OnParametersSetAsync Ocorre quando o componente recebe parâmetros e as propriedades são atribuídas.
5 OnAfterRender / OnAfterRenderAsync Ocorre depois que o componente é renderizado.
6 Dispose / DisposeAsync Se o componente implementar IDisposable ou IAsyncDisposable, o descartável apropriado ocorrerá como parte da destruição do componente.

O método SetParametersAsync

Quando um usuário visita uma página que contém um componente Blazor, o tempo de execução do Blazor cria uma instância do componente e executa o construtor padrão. Depois que o componente é construído, o tempo de execução do Blazor chama o método SetParametersAsync.

Se o componente definir algum parâmetro, o tempo de execução do Blazor injetará os valores desses parâmetros do ambiente de chamada no componente. Esses parâmetros estão contidos em um objeto ParameterView e tornam-se acessíveis para o método SetParametersAsync. Você chama o método base.SetParametersAsync para preencher as propriedades de Parameter do seu componente com esses valores.

Como alternativa, se você precisar lidar com os parâmetros de uma forma diferente, use esse método. Por exemplo, talvez seja necessário validar os parâmetros passados para o componente antes de usá-los.

Observação

O método SetParametersAsync sempre é executado quando um componente está sendo criado, mesmo que o componente não tenha nenhum parâmetro.

Entender os métodos OnInitialized e OnInitializedAsync

Os métodos OnInitialized e OnInitializedAsync podem ser substituídos para incluir funcionalidades personalizadas. Esses métodos são executados depois que o método SetParametersAsync preenche as propriedades baseadas em parâmetros do componente, que são atribuídas com ParameterAttribute ou CascadingParameterAttribute. Você executa a lógica de inicialização nesses métodos.

Se a propriedade render-mode do aplicativo for configurada como Server, os métodos OnInitialized e OnInitializedAsync serão executados somente uma vez para uma instância do componente. Se um pai do componente modificar os parâmetros do componente, o método SetParametersAsync será executado novamente, mas esses métodos não serão. Se você precisar reinicializar um componente quando os parâmetros mudarem, use o método SetParametersAsync. Se você quiser fazer a inicialização uma vez, use esses métodos.

Se a propriedade render-mode for definida como ServerPrerendered, os métodos OnInitialized e OnInitializedAsync serão executados duas vezes. Uma vez durante a fase de pré-renderização que gera a saída estática da página e novamente quando o servidor tiver estabelecido uma conexão SignalR com o navegador. Você pode realizar tarefas de inicialização caras nesses métodos, como recuperar dados de um serviço Web usados para definir o estado do componente Blazor. Nesse caso, armazene em cache as informações de estado durante a primeira execução e reutilize o estado salvo durante a segunda execução.

Todas as dependências usadas pelo componente Blazor são injetadas quando a instância é criada, mas antes que os métodos OnInitialized ou OnInitializedAsync sejam executados. Você pode usar os objetos injetados por essas dependências nos métodos OnInitialized ou OnInitializedAsync, mas não antes.

Importante

Os componentes do Blazor não dão suporte à injeção de dependência do construtor. Em vez disso, use a diretiva @inject na marcação do componente ou InjectAttribute na declaração da propriedade.

Durante a fase de pré-renderização, o código em um componente do Blazor Server não pode executar ações que exigem uma conexão com o navegador, como chamar o código JavaScript. Você deve colocar a lógica que depende de uma conexão com o navegador nos métodos OnAfterRender ou OnAfterRenderAsync.

Os métodos OnParametersSet e OnParametersSetAsync

Os métodos OnParametersSet e OnParametersSetAsync são executados após os métodos OnInitialized ou OnInitializedAsync na primeira vez em que o componente é renderizado ou após o método SetParametersAsync, caso ele não seja. Assim como SetParametersAsync, esses métodos são sempre chamados, mesmo que o componente não tenha parâmetros.

Use um dos métodos para concluir tarefas de inicialização que dependem dos valores de parâmetro do componente, como calcular valores de propriedades computadas. Não realize operações de execução prolongada, como essas em um construtor. Os construtores são síncronos e a espera da conclusão de operações de execução prolongada afeta a capacidade de resposta da página que contém o componente.

Os métodos OnAfterRender e OnAfterRenderAsync

Os métodos OnAfterRender e OnAfterRenderAsync são executados sempre que o runtime do Blazor precisa atualizar a exibição representada pelo componente na interface do usuário. Esse estado ocorre automaticamente quando:

  • O estado do componente é alterado, por exemplo, quando os métodos OnInitialized ou OnInitializedAsync ou os métodos OnParametersSet e OnParametersSetAsync são executados.
  • Um evento de interface do usuário é disparado.
  • O código do aplicativo chama o método StateHasChanged para o componente.

Quando StateHasChanged é chamado, de um evento externo ou um gatilho de interface do usuário, o componente é renderizado condicionalmente. A seguinte lista detalha a ordem das invocações de método, incluindo StateHasChanged:

  1. StateHasChanged: o componente é marcado como precisando ser renderizado novamente.
  2. ShouldRender: retorna um sinalizador que indica se o componente deve ser renderizado.
  3. BuildRenderTree: renderiza o componente.

O método StateHasChanged chama o método ShouldRender do componente. A finalidade desse método é determinar se a alteração no estado exige que o componente realize novamente a renderização da exibição. Por padrão, todas as alterações de estado disparam uma operação de renderização, mas você pode substituir o método ShouldRender e definir sua lógica de tomada de decisão. O método ShouldRenderretorna true se a exibição precisar ser renderizada novamente ou false caso contrário.

Se o componente precisar de renderização, o método BuildRenderTree será usado para gerar um modelo que possa atualizar a versão do DOM usada pelo navegador para exibir a interface do usuário. Você pode usar a implementação padrão do método fornecida pela classe ComponentBase ou substituí-la por uma lógica personalizada em caso de requisitos específicos.

Em seguida, a exibição do componente é renderizada e a interface do usuário é atualizada. Por fim, o componente executa os métodos OnAfterRender e OnAfterRenderAsync. Neste ponto, a interface do usuário está totalmente funcional e você pode interagir com JavaScript e quaisquer elementos no DOM. Use esses métodos para executar outras etapas que exigem acesso ao conteúdo totalmente renderizado, como chamar o código JavaScript da interoperabilidade JS.

Os métodos OnAfterRender e OnAfterRenderAsync utilizam um parâmetro booliano chamado firstRender. Esse parâmetro é true na primeira vez que os métodos são executados, mas false depois disso. Você pode avaliar esse parâmetro para executar operações de uso único que poderão ser desperdícios de tempo e recursos se forem repetidas sempre que o componente for renderizado.

Observação

Não confunda a pré-renderização com a primeira renderização para um componente do Blazor. A pré-renderização ocorre antes que uma conexão SignalR seja estabelecida com o navegador e gera uma versão estática de uma página. A primeira renderização ocorre quando a conexão com o navegador está totalmente ativa e todas as funcionalidades estão disponíveis.

Os métodos Dispose e DisposeAsync

Como qualquer classe .NET, um componente do Blazor pode usar recursos gerenciados e não gerenciados. O tempo de execução recupera automaticamente os recursos gerenciados. No entanto, você deve implementar as interfaces IDisposable ou IAsyncDisposable e fornecer um método Dispose ou DisposeAsync para liberar todos os recursos não gerenciados. Essa prática reduz as chances de perda de memória no servidor.

Tratar exceções em métodos de ciclo de vida

Se um método de ciclo de vida de um componente Blazor falhar, ele fechará a conexão SignalR com o navegador que, por sua vez, fará o aplicativo Blazor parar de funcionar. Para evitar esse resultado, verifique se você está preparado para lidar com exceções da lógica dos métodos de ciclo de vida. Para obter mais informações, confira Lidar com erros em aplicativos ASP.NET Core Blazor.

Verificar seus conhecimentos

1.

Qual desses eventos não faz parte do ciclo de vida do componente Blazor?

2.

Qual desses eventos não dispara o evento SetParametersAsync?