This is the fifth in a short series of blog posts where I will go beyond the introductory level and dig a bit deeper into using the Fluxor library...
For further actions, you may consider blocking this person and/or reporting abuse
Thanks for your tutorial, it is easy to follow and it's nice if you are new to Fluxor.
I think I know a way though, in which you can use a fully one-directional flow, with immutability for all the properties, and you don't need to mutate an object in your state. It only requires a bit of knowledge about the EditContext.
1) When you initialize the EditContext, it wants a model, as you said, not a changing reference. If you would supply your EditContext with IState, the wrapper object, you know it has the same reference for the lifetime of your component.
2) @bind-Value forces you to use two-directional binding. But, a little bit more verbose, you can write it out, and gain full control of the direction of the data.
Because @bind-Value="State.Value.TextProperty" is really the same as:
Value=@State.Value.TextProperty
ValueChanged=TextPropertyChanged
ValueExpression=() => State.Value.TextProperty />
In TextPropertyChanged you don't set the value, but you are free to call your Dispatcher and dispatch an action like TextPropertyChangedAction.
I learned the EditContext works with FieldIdentifiers. This is a struct that needs the ValueExpression from above to identify a field in the form and display an errormessage at the correct field. Of course then the validator uses the same FieldIdentifiers to validate and add the errorstate.
Every time you change the state, the ValueExpression will change though:
State.Value.TextProperty, after each change there will be a new "value" and a new FieldIdentifier is needed.
So, just make sure you validate only AFTER changing your state. Then you know that your ValueExpression from validation, will match with the ValueExpression of the form field values.
Happy Fluxing!
My approach is to allow the user to edit the DTO that is sent to the API.
When the form is submitted, I Dispatch an action containing that DTO.
A Reducer sets IsSaving = true
An effect calls the server
If the server indicates success then I dispatch a different action with the DTO in it
Any state that has an interest in that piece of data (e.g. Client) has a reducer that reduces the values of the DTO properties into their own immutable states.
You should avoid having mutable state.
Two thank you's!
First @mr_eking thanks for this excellent series. I've passed it along to several colleagues and it was instrumental in my decision to move forward with Fluxor for our current project.
Second @mrpmorris thank you for Fluxor and also taking the time to make this comment about using DTO's and forms. It was very helpful to me.
I see @mr_eking 's point here but I'm interested in the thoughts of @mrpmorris ,
Just getting into this pattern and wanted to get your idea straight for the immutable state of things:
Are you transforming the DTO into a record or will it be cloned in the reducer? or just passing that DTO instance in?
And when the server indicates a success, will that DTO be the same instance? or cloned or reconstructed or ...?
For the both of you: library + excellent blog + comments !
Yes, I'm doing exactly the same thing, with the one exception that I'm also storing the form's DTO (which I'm calling "model" above) into the form component's state.
I feel that's ok, since there's no chance for the state of that form's DTO to have any effect on anything else in the application's state. Not other features' states, not even its own feature's state. It merely allows the form's field values a place to live.
If there were something other than the data-bound form itself that has interest in the DTO properties then they would have to get that value via a reducer like everything else.
Hi @mr_eking
Firstly, thank you for sharing your blog posts on Fluxor and Blazor. They are very well written and helpful.
I understand your point about whether it is acceptable to "bend the rules" with regard to the immutability of the Fluxor state for this specific use case (UserFeedback). However, I believe a more generically applicable approach would be to change the code in
Feedback.razor
as follows:Treating the UserFeedbackModel as a DTO allows the use of standard Razor form features without violating the immutability principle.
Actually, if your underlying model for the edit form needs to respond to Fluxor state changes, I suggest implementing the action subscription pattern instead. In this case, I don't believe that is required at all.
As mentioned by @mrpmorris there is an important difference between the immutable application state being served up by the Fluxor framework and the mutable and not yet dispatched state of the edit form.
Thx for you response.
Yes sessionStorage should be a good solution.
As you said depends of how many states need to be saved.
But in your opinion is it in the Effects classes that we should persiste the states in session before to disptach.
Yes, pretty much. I have added another post to the series, with examples of that approach. Let me know what you think!
Thanks for your work. I am working on a Blazor Server Project (not WASM) but your posts helped me a lot so far. Now i would like to use fluxor for an image upload from the client via blazor-server to a Rest-API.
Currently, the upload is working (without fluxor), following the Microsoft-Docs, using: InputFile-Component, MultipartFormDataContent with StreamContent and HttpClient.
Is there is a good practice fluxorifying that?
I am struggling to find a appropriate way to hand over the Image/HttpContent via Action to the handling Effect since i believe actions should be serializable and it would be bad practice to read the whole image into memory and store it into the action. Not sure if i am wrong with that.
Thx for you post, very Useful.
I Have a question. How you handle if users refresh page.
Counterstate will be reset. If you want to keep counterState.
How would you implement this?
Well, you would have to take the state and store it off somewhere so that it could be retrieved later.
One place to put the values of the store might be in the browser's localStorage, which would allow you to retrieve the state later for that user on that browser.
You could also store the state in a database somewhere, so it can be retrieved by the user regardless of which browser they are using, as long as they log in so you know who they are.
But how much of the state do you store? How often? And where? How secure do you want that persisted state to be? The answers to those questions really depend on the application.