mrpmorris / Fluxor

Fluxor is a zero boilerplate Flux/Redux library for Microsoft .NET and Blazor.
MIT License
1.26k stars 144 forks source link

Blazor Server: State won't change immediately after creating new object inside STATE object #182

Closed bmarinsek closed 3 years ago

bmarinsek commented 3 years ago

Hi!

Please check the provided blazor application and it's behaviour!

Steps to reproduce the problem:

  1. click button "Click" to create new Detail object inside Application object
  2. After button is clicked alert message will appear with value of an old Detail object

Why state wont change when i create new object inside state object? When i change only property it works fine.

(Note: Detail object is used as a parameter to the TestComponent)

Is this the expected behaviour?

WebApplication11.zip

Thank you very much for any suggestion about this issue.

zbecknell commented 3 years ago

Can you upload your reproduction to a public repository rather than a zip file?

mrpmorris commented 3 years ago
  1. You click
  2. The state updates in the parent component
  3. You read the old value of a Blazor [Parameter] and display it
  4. The parent re-renders
  5. The parent passes the value to your component's parameter
  6. The child re-renders with the new value

You need to either read directly from the state, which is updated by the time the Dispatch call has finished, like so

jsRuntime.InvokeVoidAsync("alert", applicationState.Value.Application.Detail.DetailInformation);

Or, if you want your component to be passed state instead of receiving it from your store, you have to access it in OnParametersSet. Note the HasRendered is only there because you are invoking Javascript.

    bool HasRendered;
    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        HasRendered = true;
    }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        if (HasRendered)
            jsRuntime.InvokeVoidAsync("alert", Detail.DetailInformation);
    }

And also, don't alter state in code

            applicationState.Value.Application.Detail = new Detail()
            {
                DetailInformation = "Second text"
            };