Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blazor Explicit Rendering #58871

Closed
1 task done
airwedge1 opened this issue Nov 11, 2024 · 5 comments
Closed
1 task done

Blazor Explicit Rendering #58871

airwedge1 opened this issue Nov 11, 2024 · 5 comments
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. Status: Resolved

Comments

@airwedge1
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

There are many use cases where:

  1. Make change to a state.
  2. Render the page.
  3. Take an additional action.

A very simple example below: When you try to call _myRef it is null as it has not rendered yet. There are a bunch of ways usually hacky to get around the issue. Other similar issues have been raised by other individuals for example #49048

@if(_shouldShow)
{
<MyComponent @ref="_myRef"/>
}

@code {

void SomeEvent()
{
_shouldShow=true;
StateHasChanged();
_myRef.DoSomething();
}

}

Describe the solution you'd like

What we have started to do is created our own function "RenderAsync" that creates a task then manually resolve it in the OnAfterRender event. This has worked out quite well and reduces other much hackier code. We've also made this into a base class to promote re-use / organization.

        private List<TaskCompletionSource> _renderTasks = new();

        
        public virtual async Task RenderAsync()
        {
            var taskCompletion = new TaskCompletionSource();
            var task = taskCompletion.Task;

            _renderTasks.Add(taskCompletion);
            StateHasChanged();

            await task;
        }

        protected override void OnAfterRender(bool firstRender)
        {
            _renderTasks.ForEach((t) =>
            {
                t.SetResult();

            });

            _renderTasks.Clear();
        }

So then our function referenced above changes to look like the below and now _myRef is no longer null.

async Task SomeEvent()
{
_shouldShow=true;
await RenderAsync();
_myRef.DoSomething();
}

I think our solution is still a bit hacky however and there is most likely some use cases where this strategy is going to cause a bug. I think it would be beneficial to have a built in function that accomplishes the same thing as RenderAsync() that is properly unit tested / signed off on by the core Blazor team.

Additional context

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label Nov 11, 2024
@javiercn
Copy link
Member

@airwedge1 thanks for contacting us.

I don't think the solution that you folks have is correct. The only time a @ref instance is guaranteed to be valid is inside OnAfterRenderAsync.

That's the reason you see it show up as null until OnAfterRender and why you might end up with a stale @ref instance.

@mkArtakMSFT mkArtakMSFT added Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. labels Nov 11, 2024
@airwedge1
Copy link
Author

@javiercn the first code sample is meant to be incorrect. It is an example to illustrate the use case.

The code sample that contains the RenderAsync function does execute correctly. The references are assigned after rendering, OnAfterRenderAsync is called, the task is resolved and then we are returned to the SomeEvent() function. At this point _myRef is assigned and the code executes correctly.

@dotnet-policy-service dotnet-policy-service bot added Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. and removed Needs: Author Feedback The author of this issue needs to respond in order for us to continue investigating this issue. labels Nov 11, 2024
Copy link
Contributor

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

Copy link
Contributor

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

@airwedge1
Copy link
Author

This has not been resolved. Pinging to keep open

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. Needs: Attention 👋 This issue needs the attention of a contributor, typically because the OP has provided an update. Status: Resolved
Projects
None yet
Development

No branches or pull requests

3 participants