In any reasonably complex scenario, Blazor components need to be able to communicate with each other to share data. The CascadingValue component provides a mechanism for passing data to all descendant components in a hierarchy. This is useful in situations where you want to make some or all aspects of the parent component's state available to child components.
Communication from child to parent
For guidance on enabling communication from a child component back to a parent component, refer to EventCallback parameters
Descendant components opt in to cascaded values by declaring a property decorated with the [CascadingParameter]
attribute.
In the following example, a CascadingValue component exposes a value represented by the cascade
variable to two descendant components, Child1 and Child2 :
<h3>Cascading Value Demo</h3>
<CascadingValue Value=cascade>
<Child1></Child1>
<Child2></Child2>
</CascadingValue>
@code {
string cascade = "My cascading value";
}
The Child1 component opts in to the cascading value and renders it to the browser:
<h3>Child1</h3>
<p>@cascadedValue in Child 1</p>
@code {
[CascadingParameter]
string cascadedValue { get; set; }
}
The Child2
component doesn't opt in to the cascaded value:
<h3>Child 2</h3>
<Child3></Child3>
But it contains a Child3
component that opts in to the cascaded value that it's parent skipped:
<h3>Child 3</h3>
<p>@skippedCascadedValue in Child 3</p>
@code {
[CascadingParameter]
string skippedCascadedValue { get; set; }
}
The final rendered output looks like this (borders and spacing added to help identify each component):
Matching Parameters By Type
The default mechanism for matching cascading values to parameters is based on type. In the example above, the cascading value is a string
. The child components declare cascading parameters with different names, but they are share the same type - string
. Matching is successful if the value and parameter have the same type (as in the examples so far), or an implicit conversion is possible between the value's type and the parameter's type. This is illustrated by adding a cascading parameter to Child2 of type object
:
<h3>Child 2</h3>
<p>@cascade as an object</p>
<Child3></Child3>
@code {
[CascadingParameter]
object cascade { get; set; }
}
Now when the example is run, the following output appears (with the change highlighted):
Matching Parameters By Location
Consider the following example:
<CascadingValue Value=a>
<CascadingValue Value=b>
<Child1></Child1>
</CascadingValue>
</CascadingValue>
@code {
string a = "Cascading Value A";
string b = "Cascading Value B";
}
Which value will be output by the Child1 component?
<h3>Child 1</h3>
<p>@cascadedValue</p>
@code {
[CascadingParameter]
string cascadedValue { get; set; }
}
The answer is the value passed by the CascadingValue component that is closest to the Child1 component i.e. b
:
Matching Parameters By Name
It may be that you want your child component to access the value provided by the outer CascadingValue component in the example above i.e. the one that passes "Cascading Value A". You can disambiguate cascaded values that share the same type within a hierarchy by providing a unique value to the Name
property for each cascading value:
<CascadingValue Name="Value A" Value=a>
<CascadingValue Name="Value B" Value=b>
<Child1></Child1>
</CascadingValue>
</CascadingValue>
@code {
string a = "Cascading Value A";
string b = "Cascading Value B";
}
The CascadingParameter
attribute also includes a Name
property, which is set in the Child1 component to reference the value that you want to bind:
<h3>Child 1</h3>
<p>@cascadedValue</p>
@code {
[CascadingParameter(Name="Value A")]
string cascadedValue { get; set; }
}
Now the correct value is bound to the parameter:
Note that if you apply a Name
property to your CascadingParameter
, only named cascading values will be bound to it.
Modifying Cascading Values
If you modify a cascading value in the parent component, all descendants are notified of the change by default and will update accordingly. To illustrate this, here is the first arrangement again, where the CascadingValue component has two children, one of which also has a child. The value being cascaded is the current time:
<h3>Cascading Value Demo</h3>
<CascadingValue Value=cascade>
<Child1></Child1>
<Child2></Child2>
</CascadingValue>
<button @onclick=update>Update in the parent</button>
@code {
string cascade = DateTime.Now.ToLongTimeString();
void update()
{
cascade = DateTime.Now.ToLongTimeString();
}
}
This time, the parent component features a button, which when clicked will fire the update method, updating the cascading value.
Here's the output prior to the button click:
And here it is once the button has been clicked:
Sometimes, you may set cascading values that will never change. In those cases, you can set the IsFixed
property of the CascadingValue component to true
. In the next example, the highlighted line of markup is added to output the cascading value in the parent component. IsFixed
is set to true in the CascadingValue component:
<h3>Cascading Value Demo</h3>
<p>Cascading value: @cascade</p>
<CascadingValue Value=cascade IsFixed=true>
<Child1></Child1>
<Child2></Child2>
</CascadingValue>
@code {
string cascade = DateTime.Now.ToShortTimeString();
}
This setting stops descendants monitoring the CascadingValue
component for changes. It is primarily a performance optimisation. You can still change the value in the parent component, but descendant components will no longer update to reflect the new value. When the component first renders, the cascading value is the same wherever it is rendered:
Once the button is clicked, the only place that the rendered value updates is in the parent:
If you need to modify the cascading value from a child component, you can use EventCallback parameters.