Skip to content
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

MudComponentBase: Add explicit IMudStateHasChanged.StateHasChanged #6563

Merged
merged 1 commit into from
Mar 31, 2023

Conversation

ScarletKuro
Copy link
Member

@ScarletKuro ScarletKuro commented Mar 30, 2023

Description

We had an internal discussion about this in discord.
This adds IMudStateHasChanged interface with method StateHasChanged.
The interface is added to the MudComponentBase and implemented it explicitly!
This means that in order to use StateHasChanged you need to cast to the IMudStateHasChanged interface.
I still think it should be this way. It shows a clear intention, if it was that cheap and safe then Microsoft wouldn't do a breaking change by removing the public visibility for StateHasChanged.
In the end, if the user will need to call StateHasChanged for our components, he is free to use the interface as well.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Checklist:

  • The PR is submitted to the correct branch (dev).
  • My code follows the code style of this project.
  • I've added relevant tests.

@github-actions github-actions bot added enhancement New feature or request PR: needs review labels Mar 30, 2023
@ScarletKuro ScarletKuro changed the title Add consistent option for StateHasChanged() Add consistent option for StateHasChanged Mar 30, 2023
@codecov
Copy link

codecov bot commented Mar 30, 2023

Codecov Report

Patch coverage: 66.66% and project coverage change: -0.03 ⚠️

Comparison is base (2631eef) 91.47% compared to head (643baf1) 91.44%.

Additional details and impacted files
@@            Coverage Diff             @@
##              dev    #6563      +/-   ##
==========================================
- Coverage   91.47%   91.44%   -0.03%     
==========================================
  Files         393      393              
  Lines       14877    14871       -6     
==========================================
- Hits        13608    13599       -9     
- Misses       1269     1272       +3     
Impacted Files Coverage Δ
src/MudBlazor/Components/Avatar/MudAvatar.razor.cs 100.00% <ø> (ø)
src/MudBlazor/Components/Chip/MudChip.razor.cs 94.00% <ø> (-0.12%) ⬇️
src/MudBlazor/Components/DataGrid/Column.razor.cs 78.82% <0.00%> (ø)
...Components/DataGrid/DataGridColumnResizeService.cs 0.00% <0.00%> (ø)
...MudBlazor/Components/DataGrid/MudDataGrid.razor.cs 88.30% <ø> (-0.06%) ⬇️
...lazor/Components/Dialog/MudDialogInstance.razor.cs 82.67% <ø> (-0.27%) ⬇️
...c/MudBlazor/Components/ChipSet/MudChipSet.razor.cs 97.56% <50.00%> (ø)
.../MudBlazor/Components/DataGrid/HeaderCell.razor.cs 66.06% <60.00%> (ø)
src/MudBlazor/Base/MudComponentBase.cs 100.00% <100.00%> (ø)
...udBlazor/Components/Avatar/MudAvatarGroup.razor.cs 100.00% <100.00%> (ø)
... and 4 more

... and 1 file with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Member

@Mr-Technician Mr-Technician left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

@henon henon changed the title Add consistent option for StateHasChanged MudComponentBase: Add explicit IMudStateHasChange.StateHasChanged Mar 31, 2023
@henon henon merged commit 57a2a0b into MudBlazor:dev Mar 31, 2023
@henon
Copy link
Collaborator

henon commented Mar 31, 2023

Awesome, thanks @ScarletKuro

@borislavnnikolov
Copy link

What about the other components, like MudTabs and etc. ?

@henon
Copy link
Collaborator

henon commented May 5, 2023

Don't they all inherit this?

@borislavnnikolov
Copy link

Don't they all inherit this?

It is not public.

@Mr-Technician
Copy link
Member

They do @henon

@@ -45,5 +46,8 @@ public abstract class MudComponentBase : ComponentBase
/// If the UserAttributes contain an ID make it accessible for WCAG labelling of input fields
/// </summary>
public string FieldId => (UserAttributes?.ContainsKey("id") == true ? UserAttributes["id"].ToString() : $"mudinput-{Guid.NewGuid()}");

/// <inheritdoc />
void IMudStateHasChanged.StateHasChanged() => StateHasChanged();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be public, so it can be available.

Copy link
Collaborator

@henon henon May 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, that was actually my intention to make it publicly available. Probably even without the explicit interface (if the team agrees) because I am sure it will cause many questions which we'll have to answer over and over again because the method won't show up in intellisense without a cast to (IMudStateHasChanged).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got it, this may need to be documented because it is really confusing.
MudDialogInstance does not need to be casted for example.
I am trying to re render MudTabs and didn't know how to execute it until I red the PR description.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be public, so it can be available.

It is "public". The IMudStateHasChange interface is public, and all components implement this interface. This means that you can cast to this interface and call StateHasChanged, as @henon suggested. This was the primary idea.

MudDialogInstance does not need to be casted for example.

We made the MudDialogInstance more special due to its unique requirement for the title refresh. We also anticipated that many people would find it confusing when ForceRerender is removed in v7, which is why we made this decision to make it more visible.

My main goal in implementing this interface in a "hidden" manner was to align with Microsoft's logic that StateHasChanged is protected and can't be called outside of the component. However, there are cases when there is an urgent need to call it, which is why we decided to make it possible through this interface.

While @henon believes that StateHasChanged is harmless, I disagree because overusing it can cause unintended side effects, such as input or state resetting / degrade of the performance because of too much re-renders. People will complain and create issues, then we will spend time on fixing users code mistake.
Nevertheless, people who understand the reasons behind using this method can find it through refactoring.
Ultimately, the decision to create this interface was made to balance the need for urgent updates with the potential risks of overusing StateHasChanged.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rather give people a shotgun and tell them "don't shoot yourself in the foot" than hiding the shotgund and having to explain every starving trapper where to find it ;)

I am preparing a PR to make it publicly visible with a comment of caution in the docs. We'll decide as a team whether or not to merge it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your argument and I partially agree. However, in this example the user could avoid the MudAutocomplete to refresh if they knew about StateHasChanged() and refreshed other parts of the page selectively without affecting the autocomplete. So you see, it is a sharp knife, but if well documented and used correctly it can do a lot of good.

@henon I think you're misunderstanding the bug I opened. You're implying that I should call StateHasChanged more selectively, and it won't affect MudAutocomplete - but that isn't the case at all. The times I'm hitting the bug in my app are when I'm calling StateHasChanged very explicitly in a child control which is nowhere in/near the render tree of the MudAutoComplete control - but it's causing the autocomplete dropdown to dismiss regardless. This is a MudBlazor bug - for two reasons:

  1. It didn't used to happen like that - it was introduced in a MudBlazor release sometime in the last year or so
  2. You're effectively saying that no app anywhere should use StateHasChanged within a control, in case it adversely affects MudBlazor's controls. Clearly that's bogus - StateHasChanged is part of the Blazor idiom, so calling it in my own scoped controls shouldn't cause MudBlazor to break. I'm basically looking at replacing the MudAutoComplete in my app because of this bug, which makes my app unusable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't used to happen like that - it was introduced in a MudBlazor release sometime in the last year or so

Would it be difficult for you to locate the latest working version? This would greatly assist in identifying the commit responsible for the regression.

It seems highly likely that the encountered problem aligns with the one described in detail here: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/overwriting-parameters?view=aspnetcore-7.0

A comprehensive overhaul of the MudAutocomplete component is necessary. However, I cannot provide an estimated time. It is likely that this will be addressed in a future major release(v7), but for now the core team is fully occupied with other tasks. If someone is seeking a swift resolution to the issue, taking the initiative to create a pull request may be the most expedient approach since MudBlazor is a community-driven project.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be difficult for you to locate the latest working version? This would greatly assist in identifying the commit responsible for the regression.

I tried to narrow it down, but there are just too many versions, and it takes a few minutes to repro each one.

Also, understand the team is busy, but it would be good to get this fixed at some point!

Copy link
Collaborator

@henon henon Jun 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Webreaper with git bisect you'll find the commit in half an hour. I did so before for other issues. It is quite easy, see: #4303 (comment)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is another one where the user used bisect and found that the bug was in their code base: #3594 (comment)

@henon henon changed the title MudComponentBase: Add explicit IMudStateHasChange.StateHasChanged MudComponentBase: Add explicit IMudStateHasChanged.StateHasChanged May 5, 2023
henon added a commit to henon/MudBlazor that referenced this pull request May 5, 2023
@ScarletKuro ScarletKuro deleted the statechange_feature branch June 25, 2023 21:12
ilovepilav pushed a commit to ilovepilav/MudBlazor that referenced this pull request Nov 25, 2023
@Webreaper
Copy link

Any update on the plans to refactor/overhaul the statehaschanged stuff, so that this (and my associated issue #6686) is fixed?

@ScarletKuro
Copy link
Member Author

Any update on the plans to refactor/overhaul the statehaschanged stuff, so that this (and my associated issue #6686) is fixed?

This problem has nothing to do with this particular PR. The problem usually arises when you write directly to the parameters, such problem indeed exist in the core library.

About plans, I personally do not plan, MudBaseInput are very complicated components and it wasn't me who made them so it's even more harder, any change can easily destabilize multiple set of components.
But if anyone from the community or other maintainers are wishing to work on it, then a PR is welcome.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request PR: needs review
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants