Search code examples
blazorsections

Blazor Sections: How to update `SectionOutlet` in `MainLayout`?


There is a new feature called Sections in Blazor 8, and I want to use it for my Blazor Web App. I want to update a value changed in a page, but shown in a SectionOutlet in MainLayout. So I inserted a SectionOutlet in the MainLayout.razor:

<div class="top-row px-4">
    <SectionOutlet SectionName="s-test"></SectionOutlet>
    <a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>

My page for changing the value looks like

@page "/changedata"
@rendermode InteractiveServer

<SectionContent SectionName="s-test">
    @_clickCounter
</SectionContent>
<SectionContent SectionName="s-test-local">
    @_clickCounter
</SectionContent>

<button @onclick="ButtonClick">Click</button>
<SectionOutlet SectionName="s-test-local"></SectionOutlet>

@code {
    private int _clickCounter = 0;

    private void ButtonClick()
    {
        _clickCounter++;
    }
}

The value should be shown in two SectionOutlets: one local within the same page called "s-test-local", and another in MainLayout defined in the snippet above (named "s-test").

After a click on the button the current page is updated with the new value, the local Section works. But the Section in the MainLayout shows only the initial value 0, it is only rendered once.

How can I update the SectionOutlet in MainLayout after every button click as well? With this new feature I assumed, things like CascadingValues or EventCallbacks are not neccessary anymore. Do I use an inappropriate rendermode? What am I doing wrong here?


Solution

  • As you have @rendermode InteractiveServer in your page I'm guessing you have interactivity set at Per Page/Component.

    If so, the Layout is SSR rendered. It's not interactive, so you can't update it interactively. You need to set interactivity to global.

    App.razor should look like this. Note the @rendermode settings on HeadOutlet and Routes.

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <base href="/" />
        <link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
        <link rel="stylesheet" href="app.css" />
        <link rel="stylesheet" href="SO78804231.styles.css" />
        <link rel="icon" type="image/png" href="favicon.png" />
        <HeadOutlet @rendermode="InteractiveServer" />
    </head>
    
    <body>
        <Routes @rendermode="InteractiveServer" />
        <script src="_framework/blazor.web.js"></script>
    </body>
    
    </html>