I have a custom component with an event Action called TabChanged. In my Razor page I set the reference to it up like so:
<TabSet @ref="tabSet">
 ...
</TabSet>
@code {
    private TabSet tabSet;   
    ...
}
In the OnAfterRenderAsync method I assign a handler to the event:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if(firstRender)
    {
        tabSet.TabChanged += TabChanged;
    }       
}
The first time the page renders I get a System.NullReferenceException: Object reference not set to an instance of an object error.
If I switch to use subsequent renders it works fine:
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if(!firstRender)
    {
        tabSet.TabChanged += TabChanged;
    }       
}
But of course this is sloppy and I will be firing multiple event handlers as they stack up during renders.
How can I assign the reference one time and on first render? I am following the docs as outlined here
EDIT
Here is the TabSet.razor file:
@using Components.Tabs
<!-- Display the tab headers -->
<CascadingValue Value="this">
    <ul class="nav nav-tabs">
        @ChildContent
    </ul>
</CascadingValue>
<!-- Display body for only the active tab -->
<div class="nav-tabs-body" style="padding:15px; padding-top:30px;">
    @ActiveTab?.ChildContent
</div>
@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }
    public ITab ActiveTab { get; private set; }
    public event Action TabChanged;
    public void AddTab(ITab tab)
    {
        if (ActiveTab == null)
        {
            SetActiveTab(tab);
        }
    }
    public void RemoveTab(ITab tab)
    {
        if (ActiveTab == tab)
        {
            SetActiveTab(null);
        }
    }
    public void SetActiveTab(ITab tab)
    {
        if (ActiveTab != tab)
        {
            ActiveTab = tab;
            NotifyStateChanged();
            StateHasChanged();
        }
    }
    private void NotifyStateChanged() => TabChanged?.Invoke();
}
TabSet also uses Tab.razor:
@using Components.Tabs
@implements ITab
<li>
    <a @onclick="Activate" class="nav-link @TitleCssClass" role="button">
        @Title
    </a>
</li>
@code {
    [CascadingParameter]
    public TabSet ContainerTabSet { get; set; }
    [Parameter]
    public string Title { get; set; }
    [Parameter]
    public RenderFragment ChildContent { get; set; }
    private string TitleCssClass => ContainerTabSet.ActiveTab == this ? "active" : null;
    protected override void OnInitialized()
    {
        ContainerTabSet.AddTab(this);
    }
    private void Activate()
    {
        ContainerTabSet.SetActiveTab(this);
    }
}
And ITab.cs Interface
using Microsoft.AspNetCore.Components;
namespace PlatformAdmin.Components.Tabs
{
    public interface ITab
    {
        RenderFragment ChildContent { get;  }
        public string Title { get; }
    }
}
It's taken from a Steve Sanderson example found here
EDIT 2
Here is the debugger showing tabSet is null on first render:
And not null on additional renders:


 
     
     
    