-
Notifications
You must be signed in to change notification settings - Fork 26.3k
feat(core): change effect() execution timing & no-op allowSignalWrites
#57874
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
Conversation
Nice change! |
Let me explain my comment a bit. I’ve got a cold, so my brain is working at 50% of its capacity. Please excuse me if I post nonsense. Important I would never write this code. It is not about my existing code. Code example: class ExampleComponent {
child = viewChild<ElementRef>('child');
_ = effect(() => {
const child = this.child();
if (child) {
// Here user expects that `child` already has `nativeElement`, because `child` is not undefined
child.nativeElement.color = 'green';
}
});
} If I misunderstood something and the child will be colored green, please just disregard my comment. |
@e-oz that code is totally fine because the query is reactive. The effect may run twice now as opposed to once prior to the change, depending on whether the result is available during creation mode. It would be a problem if that query was using the old |
@e-oz yep, that should be fine, but this is also a great use case for |
Caretaker: this will require cl/676508958 submitted prior to merge (ok to merge the patch in advance). With that patch, this change is a no-op in g3 and does not need a presubmit. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM other than the timing note I mentioned in chat
This commit flips the flag that was added in 4e890cc, putting the new effect timing into... effect :) BREAKING CHANGE: Generally this PR has two implications: * effects which are triggered outside of change detection run as part of the change detection process instead of as a microtask. Depending on the specifics of application/test setup, this can result in them executing earlier or later (or requiring additional test steps to trigger; see below examples). * effects which are triggered during change detection (e.g. by input signals) run _earlier_, before the component's template. We've seen a few common failure cases: * Tests which used to rely on the `Promise` timing of effects now need to `await whenStable()` or call `.detectChanges()` in order for effects to run. * Tests which use faked clocks may need to fast-forward/flush the clock to cause effects to run. * `effect()`s triggered during CD could rely on the application being fully rendered (for example, they could easily read computed styles, etc). With the change, they run before the component's updates and can get incorrect answers. The recent `afterRenderEffect()` API is a natural replacement for this style of effect. * `effect()`s which synchronize with the forms system are particularly timing-sensitive and might need to adjust their initialization timing. Fixes angular#55311 Fixes angular#55808 Fixes angular#55644 Fixes angular#56863
d74afeb
to
da63106
Compare
This PR was merged into the repository by commit fc59e2a. The changes were merged into the following branches: main |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
This commit flips the flag that was added in 4e890cc, putting the new effect timing into... effect :)
BREAKING CHANGE:
Generally this PR has two implications:
effects which are triggered outside of change detection run as part of
the change detection process instead of as a microtask. Depending on the
specifics of application/test setup, this can result in them executing
earlier or later (or requiring additional test steps to trigger; see below
examples).
effects which are triggered during change detection (e.g. by input signals) run earlier, before the component's template.
We've seen a few common failure cases:
Tests which used to rely on the
Promise
timing of effects now need toawait whenStable()
or call.detectChanges()
in order for effects to run.Tests which use faked clocks may need to fast-forward/flush the clock to cause effects to run.
effect()
s triggered during CD could rely on the application being fully rendered (for example, they could easily read computed styles, etc). With the change, they run before the component's updates and can get incorrect answers. The recentafterRenderEffect()
API is a natural replacement for this style of effect.effect()
s which synchronize with the forms system are particularly timing-sensitive and might need to adjust their initialization timing.Fixes #55311
Fixes #55808
Fixes #55644
Fixes #56863