Skip to content

Bug - Loop body scoped variables appear to be lost track of #16276

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

Closed
BalazsArva opened this issue Mar 30, 2018 · 2 comments
Closed

Bug - Loop body scoped variables appear to be lost track of #16276

BalazsArva opened this issue Mar 30, 2018 · 2 comments
Labels
area-blazor Includes: Blazor, Razor Components

Comments

@BalazsArva
Copy link

I'm filing a (possible) bug. Consider the following code:

@page "/test"

@for (int i = 0; i < 10; ++i)
{
    bool boolValue = false;

    <div>
        <p>
            @boolValue
        </p>
        <button type="button" @onclick(() => { boolValue = !boolValue; })>
            Change the value to @(!boolValue)
        </button>
    </div>
}

When clicking the button, nothing changes, it appears that variables which are created in a loop body cannot be tracked.

I am not sure whether this is a bug or by design (perhaps value types in such a scope cannot be captured) so this needs clarification from the designers.

@BalazsArva BalazsArva changed the title Loop body scoped variables appear to be lost track of Bug - Loop body scoped variables appear to be lost track of Mar 30, 2018
@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Mar 30, 2018

This is as expected, though I appreciate it might not be obvious at first glance.

The markup in a Razor file gets compiled into a method. Let's call that method Render(). Each time your component renders, the Render() method is executed. Any variables defined inside that method are just locals, so they are recreated each time the method is executed, just like locals in any other C# method. As such they don't retain any state from earlier executions.

In your example, there is no state outside your Render() method. The boolValue variables are new on each Render() execution, and so writing to them doesn't achieve anything. Your event handler may trigger a new Render(), but the new invocation will produce the same output as the last one, because it's stateless.

If you want to retain state across successive renders, that state can't be local variables. It has to be properties defined on the component class itself (e.g., a property or field inside the @functions block).

@BalazsArva
Copy link
Author

@SteveSandersonMS Thanks for the explaination, it makes perfect sense. As a side note, if and when Blazor goes production ready, it might be worth keeping in mind that this should be pointed out in a very outstanding way in the docs, perhaps even a compiler warning could be implemented.

@mkArtakMSFT mkArtakMSFT transferred this issue from dotnet/blazor Oct 27, 2019
@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Oct 27, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

3 participants