fluentui-blazor icon indicating copy to clipboard operation
fluentui-blazor copied to clipboard

fix: memory / reference issues in FluentSelect

Open edson-v-schmitt opened this issue 9 months ago • 5 comments

🐛 Bug Report

While working on some fancy FluentSelect related data manipulation I noticed that once the underlying data is updated by the second time, there is a disconnect between what is shown on the screen and what is kept in memory. Not 100% sure it is FluentSelect related ... might be skills related

💻 Repro or Code Sample

https://github.com/edson-v-schmitt/FluentSelectIssue/

🤔 Expected Behavior

For the in memory list state to be consistent.

😯 Current Behavior

The second time the list is generated things break.

💁 Possible Solution

Haven't found one.

🔦 Context

I have some entities which I retrieve and populate from a backend API call for which I'd like to manipulate some properties... works like a charm the first time items are retrieved ... today I noticed that for a second set of data things are breaking.

🌍 Your Environment

  • .NET and Fluent UI Blazor library Version [e.g. 8.0.4 and 4.7.2]

edson-v-schmitt avatar May 06 '24 01:05 edson-v-schmitt

Have you tried calling StateHasChanged() to inform the user interface of these changes? I don't think this is related to FluentSelect.

dvoituron avatar May 06 '24 07:05 dvoituron

I have just added the StateHasChanged calls to the sample code ... but just like in my own code the problem persists ... on the page I created there are instructions on how to replicate. Let me know if you have issues!

edson-v-schmitt avatar May 06 '24 11:05 edson-v-schmitt

After all the testing I went thru yesterday trying to understand what was happening ... as I was having breakfast just now it occurred to me ...

This is the code I'm using to render the select control

<FluentSelect TOption="TestEnum01" ValueChanged="(newValue) => item.TestEnum01 = Enum.Parse<TestEnum01>(newValue)"> @foreach (var value in Enum.GetValues(typeof(TestEnum01))) { <FluentOption Value="@value.ToString()">@value.ToString()</FluentOption> } </FluentSelect>

if the control is never removed out of view, the code associated with ValueChanged doesn't really get updated (it seems) ... and references to old data are still referenced by the function.

It may not be FluentSelect's fault but it feels like some sort of problem in the rendering engine of the platform ... anyways ... this is the best I've come up with to explain the behavior.

edson-v-schmitt avatar May 06 '24 11:05 edson-v-schmitt

After all the testing I went thru yesterday trying to understand what was happening ... as I was having breakfast just now it occurred to me ...

This is the code I'm using to render the select control

<FluentSelect TOption="TestEnum01" ValueChanged="(newValue) => item.TestEnum01 = Enum.Parse<TestEnum01>(newValue)"> @foreach (var value in Enum.GetValues(typeof(TestEnum01))) { <FluentOption Value="@value.ToString()">@value.ToString()</FluentOption> } </FluentSelect>

if the control is never removed out of view, the code associated with ValueChanged doesn't really get updated (it seems) ... and references to old data are still referenced by the function.

It may not be FluentSelect's fault but it feels like some sort of problem in the rendering engine of the platform ... anyways ... this is the best I've come up with to explain the behavior.

Have you tried:

@code {
    public enum TestEnum01
    {
        Hello, World
    }

    private IEnumerable<TestEnum01> _items = Enum.GetValues<TestEnum01>();
    private TestEnum01 _selectedEnumValue;
}

<FluentSelect TOption="TestEnum01"
              Items="_items"
              @bind-SelectedOption="_selectedEnumValue"
              @bind-SelectedOption:after="StateHasChanged" />

ApacheTech avatar May 09 '24 12:05 ApacheTech

ApacheTec

I updated my repo ... and yes, your suggestion is simpler and it works! Thanks!

I still think that this

<FluentSelect TOption="TestEnum01" ValueChanged="(newValue) => item.TestEnum01 = Enum.Parse<TestEnum01>(newValue)"> @foreach (var value in Enum.GetValues(typeof(TestEnum01))) { <FluentOption Value="@value.ToString()">@value.ToString()</FluentOption> } </FluentSelect>

should NOT generate code that breaks the UI between one user action and the next.

edson-v-schmitt avatar May 11 '24 13:05 edson-v-schmitt

Closing this as a working solution is provided (thanks @ApacheTech )

Im not sure if the last example is more s Blazor thing than a specific Fluent issue. Had to do with the foreach and using its iterator inside the loop.

vnbaaij avatar May 11 '24 14:05 vnbaaij