-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Related to #11308. Bindings don't work properly (change behavior) when a component is surrounded by a CascadingParameter.
In my case, I am trying to wrap a third-party input in my own custom component (2 levels of binding 3rd party -> CustomTextBox -> Index.razor). You must have 2+ levels of chained binding to see the problem.
I'd like this to be reconsidered for a fix. The fact that adding a CascadingValue changes the way that bindings work is a framework bug in my opinion.
Take note of the code below with specific focus on the Index.razor page. I have 2 text box components that are nearly identical, except 1 is wrapped in a cascadingvalue tag, and another is not. Bindings work as expected for the component that is not wrapped, but notice you cannot set the value at all for the first text box (typing in the input appears to do nothing).
Index.razor
@page "/"
TextBox1Value: @TextBox1Value
TextBox2Value: @TextBox2Value
<CascadingValue Value="DateTime.Now">
<CustomTextBox @bind-Value="@TextBox1Value" Placeholder="Not working textbox"></CustomTextBox>
</CascadingValue>
<CustomTextBox @bind-Value="@TextBox2Value" Placeholder="Working textbox"></CustomTextBox>
@code{
string TextBox1Value { get; set; }
string TextBox2Value { get; set; }
}
ThirdPartyComponent.razor
<input @bind-value="@Value" @bind-value:event="oninput" placeholder="@Placeholder"/>
@code {
string _value;
[Parameter] public string Value
{
get
{
return _value;
}
set
{
if(value != _value)
{
_value = value;
ValueChanged.InvokeAsync(_value);
}
}
}
[Parameter] public EventCallback<string> ValueChanged { get; set; }
[Parameter] public string Placeholder{get;set;}
}
CustomTextBox.razor
<ThirdPartyComponent @bind-Value="Value" Placeholder="@Placeholder"></ThirdPartyComponent>
@code {
string _value;
[Parameter] public string Value
{
get
{
return _value;
}
set
{
if(value != _value)
{
_value = value;
ValueChanged.InvokeAsync(_value);
}
}
}
[Parameter] public EventCallback<string> ValueChanged { get; set; }
[Parameter] public string Placeholder{get;set;}
[CascadingParameter] public DateTime MyCascadingDate{ get; set; }
}
Notice that the TextBox1Value is never set. This is because the setter is called twice, the first time with the correct newValue, and a second time with an incorrect original value (reverts new value to original). Thus, you can never change the value simply because it is wrapped by a CascadingValue.
I understand that Microsoft suggests not to do bindings this way, however, why do bindings work differently depending on whether they are wrapped by a cascading parameter?
Expected Behavior
Expect bindings to work the same, regardless of whether they are wrapped by a cascading value or not.
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
dotnet6
Anything else?
No response