Skip to content

Commit bcea924

Browse files
committed
Ensure persisted component state gets passed at the end of streaming updates even when no components change
1 parent 6568966 commit bcea924

File tree

4 files changed

+20
-9
lines changed

4 files changed

+20
-9
lines changed

src/Components/Samples/BlazorUnitedApp/Data/WeatherForecastService.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ public class WeatherForecastService
1010
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
1111
};
1212

13-
public Task<WeatherForecast[]> GetForecastAsync(DateOnly startDate)
13+
public async Task<WeatherForecast[]> GetForecastAsync(DateOnly startDate)
1414
{
15-
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
15+
await Task.Delay(1000);
16+
return [.. Enumerable.Range(1, 5).Select(index => new WeatherForecast
1617
{
1718
Date = startDate.AddDays(index),
1819
TemperatureC = Random.Shared.Next(-20, 55),
1920
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
20-
}).ToArray());
21+
})];
2122
}
2223
}

src/Components/Samples/BlazorUnitedApp/Pages/FetchData.razor

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
@using BlazorUnitedApp.Data
33
@inject WeatherForecastService ForecastService
44

5-
<PageTitle>Weather forecast</PageTitle>
5+
<FetchDataChildren @key="0" @rendermode="InteractiveServer"></FetchDataChildren>
6+
7+
@* <PageTitle>Weather forecast</PageTitle>
68
79
<h1>Weather forecast</h1>
810
911
<p>This component demonstrates fetching data from a service.</p>
1012
11-
@if (forecasts == null)
13+
@if (Forecasts is null)
1214
{
1315
<p><em>Loading...</em></p>
1416
}
@@ -24,7 +26,7 @@ else
2426
</tr>
2527
</thead>
2628
<tbody>
27-
@foreach (var forecast in forecasts)
29+
@foreach (var forecast in Forecasts)
2830
{
2931
<tr>
3032
<td>@forecast.Date.ToShortDateString()</td>
@@ -38,10 +40,11 @@ else
3840
}
3941
4042
@code {
41-
private WeatherForecast[]? forecasts;
43+
private WeatherForecast[]? Forecasts { get; set; }
4244
4345
protected override async Task OnInitializedAsync()
4446
{
45-
forecasts = await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
47+
Forecasts ??= await ForecastService.GetForecastAsync(DateOnly.FromDateTime(DateTime.Now));
4648
}
4749
}
50+
*@

src/Components/Samples/BlazorUnitedApp/Pages/FetchDataChildren.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@using BlazorUnitedApp.Data
22
@inject WeatherForecastService ForecastService
33
@inject NavigationManager NavigationManager
4+
@attribute [StreamRendering]
45

56
<h1>Weather forecast</h1>
67

src/Components/Web.JS/src/Services/WebRootComponentManager.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,16 @@ export class WebRootComponentManager implements DescriptorHandler, RootComponent
269269

270270
private refreshRootComponents(components: Iterable<RootComponentInfo>) {
271271
const operationsByRendererId = new Map<WebRendererId, RootComponentOperation[]>();
272-
273272
for (const component of components) {
274273
const operation = this.determinePendingOperation(component);
275274
if (!operation) {
275+
if (component.assignedRendererId) {
276+
// If there are operations we will update the persisted component state for that
277+
// render mode. But if we detect a component that doesn't require any update we
278+
// still want to add an entry so that we process any persisted state update.
279+
// This case is specially common during streaming rendering.
280+
operationsByRendererId.set(component.assignedRendererId, []);
281+
}
276282
continue;
277283
}
278284

0 commit comments

Comments
 (0)