Description
🐛 Bug Report
A StreamRendering parent that updates a Param that it passes to a WASM child component doesn't update/rerender appropriately with incremental updates. I'm using an async enumerable; in my repro I slow it way down to illustrate.
💻 Repro or Code Sample
Here is the parent weather page that is stream rendered.
Weather.razor
@page "/weather"
@attribute [StreamRendering]
<PageTitle>Weather</PageTitle>
<h1>Weather Page - StreamRendering</h1>
<p>with embedded wasm WeatherComponent:</p>
<p>Data is loaded with async enumerable</p>
<WeatherComponent Forecasts="_forecasts"/>
@code {
private List<WeatherComponent.WeatherForecast>? _forecasts;
protected override async Task OnInitializedAsync()
{
await Task.Delay(400);
_forecasts = [];
await foreach (WeatherComponent.WeatherForecast f in LoadAsyncEnumerable())
{
_forecasts.Add(f);
StateHasChanged();
}
}
static async IAsyncEnumerable<WeatherComponent.WeatherForecast> LoadAsyncEnumerable()
{
DateOnly startDate = DateOnly.FromDateTime(DateTime.Now);
var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
foreach (int i in Enumerable.Range(1, 8))
{
await Task.Delay(100);
yield return new WeatherComponent.WeatherForecast
{
Date = startDate.AddDays(i),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = summaries[Random.Shared.Next(summaries.Length)]
};
}
}
}
Here is the WASM child component. Without the tabs, just the grid by itself, or a vanilla usage of just rendering a plain list, it works fine and updates smoothly as data is streamed in.
With the Tab component un-commented, it renders initially but doesn't handle updates well, flickers until all data is settled.
WeatherComponent.razor
@rendermode @(new InteractiveWebAssemblyRenderMode(true))
@* <FluentTabs @bind-ActiveTabId="@_tabId">
<FluentTab Label="One" Id="one">
*@
<FluentDataGrid Id="weathergrid" Items="@Forecasts?.AsQueryable()" GridTemplateColumns="1fr 1fr 1fr 2fr" Loading="@(Forecasts == null)" TGridItem="WeatherForecast">
<PropertyColumn Title="Date" Property="@(c => c!.Date)" Align="Align.Start" Format="yyyy-MM-dd"/>
<PropertyColumn Title="Temp. (C)" Property="@(c => c!.TemperatureC)" Align="Align.Center"/>
<PropertyColumn Title="Temp. (F)" Property="@(c => c!.TemperatureF)" Align="Align.Center"/>
<PropertyColumn Title="Summary" Property="@(c => c!.Summary)" Align="Align.End"/>
</FluentDataGrid>
@* </FluentTab>
</FluentTabs>
*@
@code {
[Parameter]
public List<WeatherForecast>? Forecasts { get; set; }
string? _tabId = "one";
public class WeatherForecast
{
public DateOnly Date { get; set; }
public int TemperatureC { get; set; }
public string? Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}
🤔 Expected Behavior
Tabs shouldn't have unique rendering properties in relation to streaming updates.
😯 Current Behavior
Without the tabs:
Without.Tab.mp4
With the tabs:
WithTab.mp4
💁 Possible Solution
I'm guessing it has something to do with JavaScript and web components.
🔦 Context
I'm trying to find the ideal way to do pre-rendering, but avoid flickers and double renders. SSR with Stream rendering as much as possible, with isolated WASM for interactive components that have props passed to them by parents works pretty great, avoiding using a web api on the client as much as possible. Data fetched on server and serialized automatically as [Parameter].
🌍 Your Environment
- OS & Device: [Windows]
- Browser [Microsoft Edge]
- .NET and Fluent UI Blazor library Version [4.11.8, .NET 9]