OnParametersSetAsync with reused component #18638
Labels
area-blazor
Includes: Blazor, Razor Components
✔️ Resolution: Answered
Resolved because the question asked by the original author has been answered.
question
Status: Resolved
Milestone
This is somewhat a follow-up from #18382. To understand where I am, let’s assume a component, similar to a tab control, where you can switch the selection and the selected item is passed to a control that should display details:
In this setup, the details component gets heavily reused, so when I want to load additional data, I will have to do that within the
OnParametersSetAsync
since the initialization would only run once for the very frist render.If I now add a cascading parameter to this setup, then what I am seeing is that the
OnParametersSetAsync
of theDetailsComponent
gets called twice. Looking at the source, this appears to be the case because direct parameters and cascading parameters are set separately. This also matches my attempts to see whether there are ever more than two calls; I couldn’t reproduce #18382 more than twice.The problem is now that I am using
OnParametersSetAsync
to load data for the component to display:This also matches what the sample does in the
FetchData
component:aspnetcore/src/Components/Samples/BlazorServerApp/Pages/FetchData.razor
Lines 42 to 45 in e276c81
Since the method is now invoked twice when the selected item changes, this also means that the data is loaded twice. So I have to go out of my way to make sure that I don’t start two separate jobs here to retrieve the data.
While that is somewhat manageable, there is a follow-up problem with this: Assuming that the data loading does not complete fast enough, the user is abled to change the selection before the loading completes. This means that the data is still loading for a value of the component that is no longer relevant. And since this does not interrupt the data loading, this also means that there are parallel tasks that will eventually complete and set the shared
Details
property.Even if I clear the
Details
value before loading (to avoid showing old data for new parameters), this can cause incorrect data to appear when the task completes and theDetails
gets set:If I now add the cascading value to this setup, then the behavior gets really odd. Occasionally, I am seeing the following where the data is not loaded for the correct item and instead only appears after the next change:
From looking at my logs, it appears that the call to
OnParametersSetAsync
from the cascading value gets called first which causes a data loading while there is still the old selected item value. That way, the data for Item 4 gets loaded although Item 1 was selected.I don’t really know where to go from here. From the way the parameters are updated, it’s not surprising that this behavior can happen. Maybe changing the
ComponentState
to combine the parameters directly and only set the parameters once on the component. Alternatively, if there was a way to prevent reusing the component instances, the data loading could be done in theOnInitializeAsync
which would not suffer from this problem.Ultimately, I am wondering what the recommended setup for a data loading situation in
OnParametersSetAsync
is, since this can get really complicated really fast. I’m currently considering switching this to a synchronous loading to avoid this problem altogether, but of course that will heavily restrict what kind of data can even be loaded.A repro project for this is over here.
The text was updated successfully, but these errors were encountered: