-
Notifications
You must be signed in to change notification settings - Fork 9.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Blazor re-render parent component reset child values #20405
Comments
I think your example is a little to complicated. I have not enough time to analyse it thoroughly but I believe there is no error in Blazor. Here is your markup: <Blazor.InputControlLabel Label="LabelValue">
<Blazor.InputControlDate @bind-Value="Date2"></Blazor.InputControlDate>
</Blazor.InputControlLabel> You have two way data binding in |
The sample is a distillation from a much larger project with even more complexity involving generics and inheritance. I'll try to make it as simple as I can, but with the problem intact. I have added logging and I refactored and cleaned it a little bit more. ConceptsThere are 3 working components in this sample
SampleThe sample in Variant 1Found here: https://github.com/JvanderStad/blazor-rerender-bug/blob/master/Pages/Index.razor#L70 Works as expected. You can enter a text, the If I follow the log messages, this is what happens: The binding also works the other way around: If I update the property The binding works as expected, changes are reflected in the UI: Variant 2Found here: https://github.com/JvanderStad/blazor-rerender-bug/blob/master/Pages/Index.razor#L73 Is the same as variant 1, however this is wrapped with a If you set the property of If I change the input=text value, the As you can see in the above log, the bound property The If it would be a non-bound, I would understand the reset of the value (as described here: dotnet/AspNetCore.Docs#17178), but in this case the |
I have cleaned it a little bit more; commit: https://github.com/JvanderStad/blazor-rerender-bug/tree/09ad3f985a77967d8c62f5df0b9fef0e99b060c9 Less code, same problem. Container.razor is a @code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
<CascadingValue Value="this">
@ChildContent
</CascadingValue> Label.razor has a @code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}
<Container>
@ChildContent
</Container> Date.razor is a bound input-text @code {
[CascadingParameter]
public Container Container { get; set; }
}
<input type="text" @bind="DisplayValue" /> If I combine those into this: Index.razor @code {
public DateTime? DateValue2 {get; set;}
}
<Label>
<Date @bind-Value="DateValue2" />
</Label> This does not seem to work |
Triage issues are really good to learn, I believe the problem is due the pollution of events but before that I would like to mention that for parent child component they have best practice here: Sticking with your approach is also possible but we need to be careful. Date.razor.DisplayValue.cs public partial class Date
{
private string _displayValue;
[Parameter]
public string DisplayValue
{
get => _displayValue;
set
{
_displayValue = value;
try
{
ValueChanged.InvokeAsync(DateTime.Parse(_displayValue));
}
catch
{
ValueChanged.InvokeAsync(null);
}
}
}
} Date.razor.Value.cs public partial class Date
{
private DateTime? _value;
[Parameter]
public DateTime? Value
{
get => _value;
set
{
if (_value == value)
{
return;
}
_value = value;
_displayValue = _value?.ToShortDateString() ?? _displayValue;
}
}
[Parameter]
public EventCallback<DateTime?> ValueChanged { get; set; }
} The main point here is So in your code (or copy the ones above, they work 😄)
That is the solution, but I still believe this is an issue, why is |
@barahonajm Legend! With your sample, dropping the EventCallback on DisplayValue and some extra state management between Value and DisplayValue I was able to make a workaround in the actual project 👍 I do think it's an issue though |
Glad you found the solution!
As far as I understand, this is the thing that's described at https://docs.microsoft.com/en-us/aspnet/core/blazor/components/?view=aspnetcore-3.1#overwritten-parameters, which explains why components shouldn't overwrite their incoming parameter values (or how it has the potential to cause unwanted effects). If I'm missing some reason why this scenario is different please let us know, ideally in a new issue with a simplified repro case. |
Describe the bug
I've been having a problem with a Blazor component wrapped in a parent resetting values due to the parent component redrawing and using 'old' values.
To Reproduce
xxx
) in the first and the second input boxThe first component updates correctly after an error. The second component also updates correctly, but the parent container will redraw itself and update the (child)component with none-updated values and so undoing the changes.
Further technical details
The text was updated successfully, but these errors were encountered: