Skip to content

Reactivity - #2219

Draft
NullVoxPopuli wants to merge 8 commits into
ember-learn:masterfrom
NullVoxPopuli:nvp/reactivity
Draft

Reactivity#2219
NullVoxPopuli wants to merge 8 commits into
ember-learn:masterfrom
NullVoxPopuli:nvp/reactivity

Conversation

@netlify

netlify Bot commented Jun 11, 2026

Copy link
Copy Markdown

Deploy Preview for ember-guides ready!

Name Link
🔨 Latest commit ffd867a
🔍 Latest deploy log https://app.netlify.com/projects/ember-guides/deploys/6a78dcf4830534000856b7a8
😎 Deploy Preview https://deploy-preview-2219--ember-guides.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

NullVoxPopuli-ai-agent added a commit to NullVoxPopuli-ai-agent/rfcs that referenced this pull request Jul 31, 2026
- Motivation references the in-flight reactivity guides
  (ember-learn/guides-source#2219) instead of claiming docs are sparse
- remove the derived-vs-cached clarification paragraph (the guides
  cover it; not an ambiguation)
- move the RFC 615 relationship to the Appendix, without any
  de-emphasize/deprecate intent

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread guides/release/in-depth-topics/reactivity/derived-state.md Outdated
previously in the same computation.
```

This is sometimes called the _backtracking assertion_: render evaluates your

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-This is sometimes called the _backtracking assertion_: render evaluates your …
+This backtracking assertion evaluates your …

Comment thread guides/release/in-depth-topics/reactivity/index.md Outdated
Comment on lines +112 to +113
When a write that changes nothing shouldn't dirty anything, the decorator
accepts an options form, `@tracked({ equals })`, that skips invalidation

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool!

Depends on release of emberjs/ember.js#21471, right? starting with 7.3.0?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea, tho I think these docs are required to release in 7.3

@kategengler knows the task<->dependency chain.

Comment thread guides/release/in-depth-topics/reactivity/root-state.md Outdated
Comment thread guides/release/in-depth-topics/reactivity/root-state.md
@johanrd

johanrd commented Jul 31, 2026

Copy link
Copy Markdown

@NullVoxPopuli this was a great read – thanks! Also very exited to learn about the overloaded tracked of 7.3.

NullVoxPopuli-ai-agent added a commit to NullVoxPopuli-ai-agent/rfcs that referenced this pull request Jul 31, 2026
- Motivation references the in-flight reactivity guides
  (ember-learn/guides-source#2219) instead of claiming docs are sparse
- remove the derived-vs-cached clarification paragraph (the guides
  cover it; not an ambiguation)
- move the RFC 615 relationship to the Appendix, without any
  de-emphasize/deprecate intent

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
NullVoxPopuli added a commit to NullVoxPopuli/rfcs that referenced this pull request Jul 31, 2026
* Add RFC: Overload cached for non-class use

Derived-state companion to RFC 1071 (overloaded tracked). Re-uses the
Reactive/ReadOnlyReactive interfaces defined there; cached(fn, options)
returns a read-only CachedValue.


* Fill in proposal PR URL

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Do not conflate derived state with cached state

Derived state is just plain functions and needs no API; cached() is
opt-in memoization of a derivation. Reword Summary, Motivation, usage
headings, and How We Teach accordingly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Address review: guides link, drop terms paragraph, RFC 615 to appendix

- Motivation references the in-flight reactivity guides
  (ember-learn/guides-source#2219) instead of claiming docs are sparse
- remove the derived-vs-cached clarification paragraph (the guides
  cover it; not an ambiguation)
- move the RFC 615 relationship to the Appendix, without any
  de-emphasize/deprecate intent

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Address review: drop equals, drop 'memoization' wording

- remove the equals option from the proposed API entirely (calling fn
  is the expensive part; re-running it to discard the result is silly);
  noted as deferred in the Appendix
- say caching, not memoization, throughout
- reword the 'born a ReadOnlyReactive' sentence
- drop the implementation-would-be-lower aside

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Apply suggestion from @NullVoxPopuli

* Address review: get on ReadOnlyReactive, trim examples and mentions

- no new CachedValue interface; add get to ReadOnlyReactive instead
  (an RFC 1071 oversight) and return ReadOnlyReactive from cached()
- apply suggested guides sentence (drop 'over the years')
- Starbeam only in prior art; resources are a different concept
- remove the contrived nested-let template example

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: NullVoxPopuli-ai-agent <268630448+NullVoxPopuli-ai-agent@users.noreply.github.com>
Co-authored-by: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds advanced reactivity guidance supporting RFC #1071’s release advancement.

Changes:

  • Adds guides for root state, derived state, and effects.
  • Expands autotracking documentation and cross-references.
  • Updates navigation and spelling terminology.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
.local.dic Adds reactivity terminology.
guides/release/pages.yml Adds reactivity navigation.
guides/release/in-depth-topics/autotracking-in-depth.md Expands tracking references and examples.
guides/release/in-depth-topics/reactivity/index.md Introduces the reactivity model.
guides/release/in-depth-topics/reactivity/root-state.md Documents reactive root state.
guides/release/in-depth-topics/reactivity/derived-state.md Documents derivations and caching.
guides/release/in-depth-topics/reactivity/inputs-and-outputs.md Documents effects, lifetimes, and async behavior.
Suppressed comments (1)

guides/release/in-depth-topics/reactivity/root-state.md:230

  • Keeping a tracked array's identity stable is useful, but mutating it does not guarantee that only the changed entry's consumers invalidate: current trackedArray writes dirty the collection tag. Preserve the identity recommendation without promising narrower invalidation.
a one-item change gets treated as if the entire array were new. Retain
identity wherever possible: keep one long-lived tracked collection and mutate
it, so that the system invalidates only what actually changed. Replacement is

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread guides/release/in-depth-topics/reactivity/root-state.md
Comment on lines +54 to +58
Storing derived values is sometimes pitched as an optimization. However,
autotracking already recomputes lazily, and only when inputs change, so the
optimization is usually imaginary. When a derivation really is expensive, you
can [cache it](../derived-state/#toc_caching) instead of promoting it to root
state.
Comment thread guides/release/in-depth-topics/reactivity/root-state.md Outdated
Comment on lines +367 to +369
`tracked` also works as a plain function. Called with a value instead of
applied as a decorator, it returns a standalone reactive value - root state
that isn't attached to any class:

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while true, I'm not sure how beneficial it is to mention in these docs.

This is implementation caveats that are very edge casey.

Comment on lines +154 to +156
- Once-per-change semantics. If a derivation must observably run at most once
per change (because it allocates, logs, or is just very hot), `@cached`
guarantees that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷 I don't know how to best phrase this. sounds good

Comment thread guides/release/in-depth-topics/reactivity/root-state.md
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (6)

guides/release/in-depth-topics/reactivity/root-state.md:209

  • This copy guarantee does not hold for trackedWeakMap or trackedWeakSet: weak collections are not iterable, so Ember wraps and mutates a supplied weak collection instead of cloning it. Narrow the guarantee or document that exception.
to know: the collection functions copy the data you pass in, so mutating the
tracked collection never mutates the original; and tracked collections are
shallow - `trackedObject`'s properties are tracked, but objects stored inside
it are ordinary objects unless you wrap them too. See

guides/release/in-depth-topics/reactivity/inputs-and-outputs.md:212

  • A promise can reject with a falsy reason such as undefined or null. In that case status becomes rejected, but this condition falls through to the success branch and dereferences this.user.value.name while value is still null. Select the branch from status, which is the request-state discriminator.
    {{else if this.user.error}}

guides/release/in-depth-topics/reactivity/index.md:114

  • This overstates the scope and lifetime of the conditional dependency: another consumer can still be invalidated by nickname, and displayName stops depending on it if the condition later switches back. Describe invalidation through this getter and only while its branch is active.
While `useNickname` is `false`, changes to `nickname` don't invalidate
anything, because `displayName` never read it. If `useNickname` becomes
`true`, the next evaluation reads `nickname`, and from then on changes to it
propagate. The dependency graph rewires itself on every run.

guides/release/in-depth-topics/reactivity/index.md:136

  • With the new @tracked({ equals }) form, a write invokes the user-provided equality callback synchronously, so it is no longer true that no user code runs. The pull-based guarantee is specifically that writes do not execute derivations/getters; phrase it in those terms.
Autotracking is pull-based. When you write to a tracked property, no user
code runs at all. Your getters are not re-evaluated; nothing is recomputed.
The write just lets the renderer know that something it consumed is out of

guides/release/in-depth-topics/reactivity/derived-state.md:199

  • tracked is unused in this example. Keeping the import makes copied code fail the default unused-import lint rule and obscures that a plain function needs no tracking API.
import { tracked } from '@glimmer/tracking';

guides/release/in-depth-topics/reactivity/inputs-and-outputs.md:88

  • This chart is canvas-only, so its data has no accessible text representation for screen-reader users. Add an equivalent table/summary or an accessible name and description derived from the chart data; the appropriate representation depends on the data being visualized.
  <canvas {{drawChart @chartData}}></canvas>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants