fluentui-blazor
fluentui-blazor copied to clipboard
fix: uncontrolled UI updates of values bound to FluentUI components when using blazorserver and callbacks with some workload
🐛 Bug Report
Updating values which are two way bound to a FluentUI component during a "@onclick" callback in a Blazor server app will lead to uncontrolled repeated updates if the callback method did not return before a subsequent call.
This issue does not appear on client side Blazor (blazorwasm)!
💻 Repro or Code Sample
The Issue was found using @fluentui/[email protected] and Microsoft.Fast.Components.FluentUI 1.1.0.
Use your existing Blazor server app or create a new one following these steps:
-
dotnet new blazorserver -o BugFluentUIApp
-
cd BugFluentUIApp
-
dotnet add package Microsoft.Fast.Components.FluentUI
-
npm install --save @fluentui/web-components
- move
node_modules/@fluentui\web-components/dist/web-components.min.js
to folderwwwroot/script
- add
<script type="module" src="script/web-components.min.js"></script>
toPages/_Layout.cshtml
at the end of the head section - create new folder
Components
- create new file
MyItem.razor
insideComponents
folder - add content of the
MyItem.razor
component below - add
<BugFluentUIApp.Components.MyItem/>
toPages/Index.razor
- start application and press on the presented buttons
Contents of MyItem.razor
@using Microsoft.Fast.Components.FluentUI;
@if (FromInside)
{
// "normal" use
<button @onclick="UpdateAsync">Update Async</button>
<button @onclick="UpdateBlocking">Update Blocking</button>
<button @onclick="UpdateBlockingAsync">Update Blocking Async</button>
<button @onclick="UpdateBlockingAsync_Workaround">Update Blocking Async Workaround</button>
<br>
@if (UseNumberField)
{
<FluentNumberField @bind-Value=BoundValue/>
// you can also use a slider here
//<FluentSlider @bind-Value=BoundValue/>
}
else
{
<input @bind-value=BoundValue />
}
@BoundValue
}
else
{
// setup to instance to show test
<p>Press rapidly on the buttons. You will see uncontrolled updates using the 2nd and 3rd buttons in the version using the @nameof(FluentNumberField<int>) </p>
<p>Binding the value to an input element (working):</p>
<MyItem FromInside=true UseNumberField=false />
<br />
<p>Binding the value to an @nameof(FluentNumberField<int>) element (broken):</p>
<MyItem FromInside=true UseNumberField=true />
}
@code
{
[Parameter]
public bool FromInside { get; set; }
[Parameter]
public bool UseNumberField { get; set; }
public int BoundValue;
static int c;
// ok
public async Task UpdateAsync()
{
await Task.Delay(500);
BoundValue = ++c;
}
// broken
public void UpdateBlocking()
{
// do some work which might block
int i;
i = 100000000;
while (i-- > 0) ;
BoundValue = ++c;
}
// still broken
public async Task UpdateBlockingAsync()
{
await Task.Delay(10);
// do some blocking work inside a task
UpdateBlocking();
await Task.Delay(10);
}
// ok
public Task UpdateBlockingAsync_Workaround()
{
return Task.Run(UpdateBlocking);
}
}
🤔 Expected Behavior
Values which are bound to FluentUI components should only update when changed by user or by component code.
😯 Current Behavior
https://user-images.githubusercontent.com/609797/154707861-a55c27d0-ac82-4fc2-a431-11cce1091c7a.mp4
If you press the buttons "Update Blocking" or "Update Blocking Async" in the second row rapidly the bound values keep updating forever. (Even after you have stopped pressing the buttons.)
For comparison a value is bound to a non FluentUI input in the first row. Pressing these buttons do not trigger the issue.
💁 Possible Solution
🔦 Context
If a user triggers this kind of issue the FluentUI components having bound values let the application run wild and not usable anymore. For example a slider or a number field which controls pagination.
🌍 Your Environment
- OS & Device: Windows 10 (21H1) on PC
- Browser Microsoft Edge, Google Chrome & Mozilla FireFox
- .NET 6.0
- Microsoft.Fast.Components.FluentUI 1.1.0
- @fluentui/[email protected]
I can reproduce the error. No idea yet what is causing this.
Is there any specific reason you are installing the web-components package? It is not needed for the Microsoft.Fast.Components.FluentUI package to do its thing...
Is there any specific reason you are installing the web-components package?
I just installed the package because I needed the web-components version number for this bug report for better reproducibility.
Your "Getting Started" section mentions to use this script element
<script type="module" src="https://cdn.jsdelivr.net/npm/@fluentui/web-components/dist/web-components.min.js"></script>
to get the latest version. (Which i was using.)
But I have no clue to find out which version this 'latest' version is.
So, I installed the npm module to get the web-components.min.js
and the matching version number.
I just installed the package because I needed the web-components version number for this bug report for better reproducibility.
That's good! Hadn't thought about that.
Thid is no longer happening in the latest version. Closing this