microsoft / fluentui-blazor

Microsoft Fluent UI Blazor components library. For use with ASP.NET Core Blazor applications
https://www.fluentui-blazor.net
MIT License
3.23k stars 294 forks source link

fix: memory / reference issues in FluentSelect #2012

Closed edson-v-schmitt closed 1 week ago

edson-v-schmitt commented 1 week ago

🐛 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

dvoituron commented 1 week ago

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

edson-v-schmitt commented 1 week ago

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 commented 1 week ago

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(newValue)"> @foreach (var value in Enum.GetValues(typeof(TestEnum01))) {

@value.ToString()
          }
        </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.

ApacheTech commented 1 week ago

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" />
edson-v-schmitt commented 1 week ago

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(newValue)"> @foreach (var value in Enum.GetValues(typeof(TestEnum01))) {

@value.ToString()
          }
        </FluentSelect>`

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

vnbaaij commented 1 week ago

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.