Cascading Values And Parameters In Razor Components

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

Blazor Cascading Values
We use the CascadingValue component when the parent wants to share data with its descendants

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):

Blazor Cascading Values

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):

Blazor Cascading Values

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:

Blazor Cascading Values

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:

Blazor Cascading Values

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:

Blazor Update Cascading Values

And here it is once the button has been clicked:

Blazor Update Cascading Values

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:

Fixeding Cascaded Values in Blazor

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.

Last updated: 15/02/2023 08:59:24

Latest Updates

© 2023 - 2024 - Mike Brind.
All rights reserved.
Contact me at Outlook.com