There are several effective ways to share a single model (data object) between multiple child components in Blazor WebAssembly. Here are the best approaches:
1. Cascading Parameters (Best for hierarchical components)
<!-- ParentComponent.razor -->
@page "/parent"
<CascadingValue Value="@SharedModel">
    <ChildComponent1 />
    <ChildComponent2 />
</CascadingValue>
@code {
    private MyModel SharedModel { get; set; } = new MyModel();
}
<!-- ChildComponent1.razor -->
@code {
    [CascadingParameter]
    public MyModel SharedModel { get; set; }
}
<!-- ChildComponent2.razor -->
@code {
    [CascadingParameter]
    public MyModel SharedModel { get; set; }
}2. Component Parameters (Best for direct parent-child relationships)
<!-- ParentComponent.razor -->
@page "/parent"
<ChildComponent1 Model="@SharedModel" />
<ChildComponent2 Model="@SharedModel" />
@code {
    private MyModel SharedModel { get; set; } = new MyModel();
}
<!-- ChildComponent1.razor -->
@code {
    [Parameter]
    public MyModel Model { get; set; }
}
<!-- ChildComponent2.razor -->
@code {
    [Parameter]
    public MyModel Model { get; set; }
}3. State Management Service (Best for app-wide sharing)
// SharedModelService.cs
public class SharedModelService
{
    private MyModel _model = new();
    
    public MyModel Model 
    {
        get => _model;
        set
        {
            _model = value;
            NotifyStateChanged();
        }
    }
    
    public event Action OnChange;
    
    private void NotifyStateChanged() => OnChange?.Invoke();
}Register the service in Program.cs:
builder.Services.AddSingleton<SharedModelService>();Use in components:
@inject SharedModelService ModelService
@code {
    protected override void OnInitialized()
    {
        ModelService.OnChange += StateHasChanged;
    }
    
    private void UpdateModel()
    {
        ModelService.Model.Property = "New Value";
    }
}4. EventCallback Pattern (For parent-child communication)
<!-- ParentComponent.razor -->
@page "/parent"
<ChildComponent1 Model="@SharedModel" ModelChanged="@HandleModelChanged" />
<ChildComponent2 Model="@SharedModel" ModelChanged="@HandleModelChanged" />
@code {
    private MyModel SharedModel { get; set; } = new();
    
    private void HandleModelChanged(MyModel updatedModel)
    {
        SharedModel = updatedModel;
        StateHasChanged(); // Refresh all components
    }
}
<!-- ChildComponent1.razor -->
@code {
    [Parameter]
    public MyModel Model { get; set; }
    
    [Parameter]
    public EventCallback<MyModel> ModelChanged { get; set; }
    
    private async Task UpdateModel()
    {
        Model.Property = "New Value";
        await ModelChanged.InvokeAsync(Model);
    }
}5. Fluxor/Redux Pattern (For complex state management)
// Install package
dotnet add package Fluxor.Blazor.Web
// Define state
public record MyModelState
{
    public MyModel Model { get; init; } = new();
}
// Define actions
public record UpdateModelAction(MyModel Model);
// Create reducer
public static class Reducers
{
    [ReducerMethod]
    public static MyModelState ReduceUpdateModelAction(MyModelState state, UpdateModelAction action)
        => state with { Model = action.Model };
}Use in components:
@inject IState<MyModelState> ModelState
@inject IDispatcher Dispatcher
<p>@ModelState.Value.Model.Property</p>
<button @onclick="UpdateModel">Update</button>
@code {
    private void UpdateModel()
    {
        var updatedModel = ModelState.Value.Model with { Property = "New Value" };
        Dispatcher.Dispatch(new UpdateModelAction(updatedModel));
    }
}- For simple parent-child relationships: Use Component Parameters
- For deep component trees: Use Cascading Parameters
- For app-wide state: Use State Management Service or Fluxor
- For complex applications: Consider Fluxor/Redux pattern
- Immutable models: When sharing models, consider making them immutable or implementing proper change notifications
Performance Considerations
- Avoid excessive re-rendering by implementing ShouldRender
- Use [Parameter] public MyModel Model { get; set; }carefully as it can cause unnecessary renders
- For large models, consider using view models or DTOs instead of full domain models

 Add to favorites
Add to favorites