Closed panchoaby closed 8 months ago
How do you tell the difference between a pre-render and wasm execution?
We can use ApplicationState.TryTakeFromJson for that, basically if it returns true that means you are on the client as in the server the value should not be persisted yet.
Given this is the case only for the first time you call the method for a particular value. After that i guess it removes it from the storage.
It is a bit odd, but i did not find another way to check this and I see that this is how the documentation differentiates between server and client on the OnInitializedAsync method
I think you could do this with a Middleware.
If on the client then don't allow StoreInitialzed action to dispatch, deserialize from that state instead.
Yes, a Middleware will work for restoring the ReduxDevTools with the actions dispatched on the server. For the StoreInitialized action a bypass bool in the Store class constructor will do, unless there is another way to suppress it that I do not see.
But for the first point of keeping track of the effects I am not sure how to do it with a middleware without modifying the Store class as the executedEffect list of tasks is a local variable and there is no list of all currently running tasks that I can persist and restart on the client. Unless I am missing something.
You won't need to know an effect executed, you only need to know
Yes, for the current state of all features is easy to retrieve with the current implementation from the Store, and agreed that RDTools is more of a nice to have but you might have the following situation: ActionA triggers EffectA which lets say retrives data from ApiA and dispatches an ActionB to store the response using ReducerA ActionB => EffectB (ApiB) =>ActionC =>ReducerB And so on so that the effect are chained
At the cutoff point in the server will know the state but not if EffectB for example is finished or not and when we restore it on the client we will have to restart everything with ActionA even if we have the data from ApiA already in the state and if we knew what effects were still executing we could restart them on the client which will remove the flickering on overwriting data with previous states and make the app faster as we do not duplicate code.
I doubt you'll get the results of an asynchronous API call in the state before the server renders and sends the state to the client. Does it?
Usually no, but it really depends on the app logic, the api call was just an example
Does Blazor even support that yet?
If you are referring to prerendering, then yes. I have already deployed an app using wasm prerendering and the results are very good in terms of user experience.
I would be happy to try and implement the above mentioned changes to a branch and, depending on the results, see if it is something you would like to be added to the next release.
Not just prerendering, also transferring the components' states down to the client too?
Oh sorry, misunderstood. Yes that is supported since .NET 6 (from what I can see in the documentation) but I have only implemented in .NET 7 in my app so I can only vouch for it. Link to docs
@panchoaby Do you have an update on this? Did you get Fluxor and Blazor Wasm Prerendering working?
@JeremyVm I have some progress but I was not able to finish it as this work was deprioritized in my project, if you need it you can use the StateHydrator class from above to sync the state from server to client but unfortunately the actions will be dispatched again on the client (which might not be a problem depending on your usecase)
@panchoaby Thanks for your reply. At the moment I'm not really using it as my data never gets downloaded as dispatchers are not async. How did you bypass this?
Context
Just migrated my current Blazor app from WASM to WASM Prerendered. Basically the app loads twice, once on the server and once on the client with the possibility of hydrating the data gathered on the server on the client using the Persisted Component State service.
At first I had a flicker in the page, as first the data was retrieved on the server and it returned the static content needed to display the page and after, when the WASM loaded it would run the app and it will retrieve the data again, hence the flicker.
To fix this i created a StateHydrator component to restore on the client side the last state available on the server:
This works fine the only issue is that the app does again all the calls as the StoreInitializedAction is triggered on the client.
Proposed solution