You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<p>In Blazor, cascading parameters enable developers to pass data across multiple levels of a component tree without explicitly passing it through each intermediate component (prop drilling). This tutorial introduces the following aspects of using cascading parameters:</p>
3
+
<ul>
4
+
<li>Different approaches to using cascading parameters.</li>
5
+
<li>Passing and updating a parameter with the root level technique.</li>
6
+
<li>Passing, updating, and overriding a parameter with the <code>CascadingValue</code> component</li>
7
+
</ul>
8
+
<hrclass="my-4" />
9
+
<h1>Different Approaches to Using Cascading Parameters</h1>
10
+
<p>In Blazor, cascading parameters can be implemented in 2 primary ways: registering them at the root level in <code>Program.cs</code> (root-level technique) or using the <code>CascadingValue</code> component within specific parts of the component tree. Each approach has distinct characteristics, as outlined in the comparison table below:</p>
<li><strong>Root-Level Technique</strong>: By providing a cascading parameter in <code>Program.cs</code>, it becomes available to all components in the app. This method automatically updates the UI when the value changes but doesn’t allow overriding at lower levels.</li>
41
+
<li><strong><code>CascadingValue</code> Component</strong>: Using <code>CascadingValue</code> within a component allows for more control, enabling you to override the parameter in specific branches of the tree. However, UI updates require manual triggering (e.g., via <code>StateHasChanged</code>).</li>
42
+
</ul>
43
+
<blockquote>Do not use the root level technique as a way to register a singleton/scoped service. The root level cascading parameter is designed only for passing parameters, not for passing services. If you need a service, use the dependency injection feature instead.</blockquote>
44
+
<hrclass="my-4" />
45
+
<h1>Passing and Updating a Parameter with the Root Level Technique</h1>
46
+
<p>You can register cascading parameters in Program.cs to provide site-wide data, it is particularly effective for scenarios like theme settings or account information, where a single value needs to be shared across the entire app.</p>
47
+
<ol>
48
+
<li>Define the parameter model (if any). Keep in mind that while this example uses a class (<code>RootLevelSampleModel</code>) as the cascading parameter, you're not limited to classes. The root level technique also supports registering struct-typed values, such as <code>string</code>, <code>int</code>, <code>bool</code>, and more.</li>
49
+
</ol>
50
+
<prelanguage="csharp">public class RootLevelSampleModel
51
+
{
52
+
public string Message { get; set; } = "";
53
+
}</pre>
54
+
<olstart="2">
55
+
<li>Register Parameters in <code>Program.cs</code>.</li>
56
+
</ol>
57
+
<prelanguage="csharp">builder.Services.AddCascadingValue<RootLevelSampleModel>(sp => new RootLevelSampleModel
58
+
{
59
+
Message = "Hello Blazor School!"
60
+
});</pre>
61
+
<p>To register 2 parameters of the same type, use the <code>Name</code> parameter to differentiate them:</p>
62
+
<prelanguage="csharp">builder.Services.AddCascadingValue&lt;RootLevelSampleModel&gt;(&quot;Variant2&quot;, sp =&gt; new RootLevelSampleModel
<li>Define the parameter model: In the parameter model, add <code>CascadingValueSource<T></code> where <code>T</code> is the parameter model itself.</li>
83
+
</ol>
84
+
<prelanguage="csharp">public class RootLevelUpdatingModel
85
+
{
86
+
public string Message { get; set; } = "";
87
+
public CascadingValueSource<RootLevelUpdatingModel>? Source { get; set; }
public RootLevelUpdatingModel? Sample { get; set; }
113
+
114
+
public async Task UpdateValueAsync()
115
+
{
116
+
if (Sample is not null && Sample.Source is not null)
117
+
{
118
+
Sample.Message = "Overridden from Component2";
119
+
await Sample.Source.NotifyChangedAsync();
120
+
}
121
+
}
122
+
}</pre>
123
+
<hrclass="my-4" />
124
+
<h1>Passing, Updating, and Overriding a Parameter with the <code>CascadingValue</code> Component</h1>
125
+
<p>The <code>CascadingValue</code> component allows you to pass parameters across a component tree, with the added flexibility of updating and overriding them at different levels. This technique is particularly useful for scenarios like multilingual websites, where different sections might display distinct languages simultaneously.</p>
126
+
<ol>
127
+
<li>Define the parameter model (optional). While you can use simple types like string or int, a class provides more structure for complex data.</li>
128
+
</ol>
129
+
<prelanguage="csharp">public class UsingCascadingValueModel
130
+
{
131
+
public string Message { get; set; } = "";
132
+
}</pre>
133
+
<olstart="2">
134
+
<li>Pass the Parameter Using <code>CascadingValue</code> in an ancestor component.</li>
public UsingCascadingValueModel Model { get; set; } = new()
143
+
{
144
+
Message = "Hello from SimpleCascadingValueExample"
145
+
};
146
+
}</pre>
147
+
<p>In this example, we are not updating the parameter, so we set <code>IsFixed</code> to <code>true</code>. Setting <code>IsFixed</code> to <code>true</code> will not allow the parameter to be updated but will yield better performance.</p>
148
+
<olstart="3">
149
+
<li>Access the parameter in a descendant component.</li>
<li>Define the parameter and update logic in the ancestor component. Pass both the parameter and the component instance (<code>this</code>) using nested <code>CascadingValue</code>.</li>
public UsingCascadingValueModel? Sample { get; set; }
201
+
202
+
[CascadingParameter]
203
+
public UpdateCascadingValueExample? Source { get; set; }
204
+
205
+
public async Task UpdateValueAsync()
206
+
{
207
+
if (Source is not null)
208
+
{
209
+
Source.UpdateModelMessage("Update from Component2");
210
+
}
211
+
}
212
+
}</pre>
213
+
<h3>Overriding Parameter</h3>
214
+
<p>A parameter passed by <code>CascadingValue</code> can be overridden to have different values in different branches. Furthermore, a descendant component can override the parameter value in any ancestor component.</p>
215
+
<p>We will set up the example with 4 levels: <code>OverrideCascadingValueExample</code> as the ancestor component, <code>Component1</code> as Level 0, <code>Component2</code> as Level 1, and <code>Component3</code> as Level 2. The parameter will be passed from <code>OverrideCascadingValueExample</code> and will be overridden in <code>Component2</code>, and then updated in <code>Component3</code>.</p>
<li>Define the parameter and update logic in the ancestor component. Pass the component instance and parameter using nested <code>CascadingValue</code>.</li>
public UsingCascadingValueModel Model { get; set; } = new()
228
+
{
229
+
Message = "Hello from OverrideCascadingValueExample"
230
+
};
231
+
232
+
public void UpdateModel(string message)
233
+
{
234
+
Model.Message = message;
235
+
StateHasChanged();
236
+
}
237
+
}</pre>
238
+
<olstart="2">
239
+
<li>In the descendant component where you want to override the parameter, declare the parameter and the update logic. Pass the current instance (<code>this</code>) and the overridden parameter using <code>CascadingValue</code>.</li>
0 commit comments