Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .local.dic
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ debounce
declaratively
DefinitelyTyped
deps
destroyables
destructor
destructors
dev
draggable
dropdown
Expand Down Expand Up @@ -136,6 +139,9 @@ LSP
Mapbox
TomTom
MDN
memoization
memoize
memoized
metaprogramming
misspelt
mixin
Expand Down Expand Up @@ -166,13 +172,15 @@ pre-transition
pre-transition
preload
prepend
poller
prepended
presentational
Presentational
PRs
readme
readonly
recognizers
recomputation
recursing
Redux
relayout
Expand All @@ -196,9 +204,12 @@ screencasting
selectable
self-referentiality
serverless
shorthands
Signalium
singularize
Splattributes
SSR
Starbeam
stateful
subclassed
subclasses
Expand All @@ -218,6 +229,7 @@ synergistically
syntaxes
tagless
TalkBack
TC39
teardown
template-lifecycle-dom-and-modifiers
templating
Expand All @@ -237,6 +249,7 @@ typechecker
typings
UIs
un-representable
uncached
unordered
unsilence
unstyled
Expand Down
50 changes: 43 additions & 7 deletions guides/release/in-depth-topics/autotracking-in-depth.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
Autotracking is how Ember's _reactivity_ model works - how it decides what to
rerender, and when. This guide covers tracking in more depth, including how it
can be used in various types of classes, and how it interacts with arrays and
POJOs.
rerender, and when. This guide covers the mechanics of tracking in more depth,
including how it can be used in various types of classes, and how it interacts
with arrays and POJOs. For the concepts behind the system - and guidance on
designing your application's state - see
[Thinking in Reactivity](../reactivity/).

## Autotracking Basics

Expand Down Expand Up @@ -195,7 +197,10 @@ export default class HelloComponent extends Component {

This will also trigger a rerender. No matter where the update occurs, updating
a tracked property will let Ember know to rerender any affected portion of the
app.
app. Writing to tracked state from callbacks like this is the standard way
data from the outside world enters Ember's reactivity system - see
[Inputs and Outputs](../reactivity/inputs-and-outputs/) for more on
this pattern.

### Tracking Through Methods

Expand Down Expand Up @@ -266,6 +271,8 @@ Tracked properties can also be applied to your own custom classes, and used
within your components and routes:

```js {data-filename=src/utils/person.js}
import { tracked } from '@glimmer/tracking';

export default class Person {
@tracked title;
@tracked name;
Expand Down Expand Up @@ -314,7 +321,7 @@ export default class ApplicationRouteComponent extends Component {
```

As long as the properties are tracked, and accessed when rendering the template
directly or indirectly, everything should update as expected
directly or indirectly, everything should update as expected.

### Plain Old JavaScript Objects (POJOs)

Expand All @@ -341,6 +348,10 @@ All property reading and writing on this object is automatically tracked.
`obj.c.somethingDeeper = 5` would not be tracked unless you've also made sure
that the contents of `obj.c` is itself another `trackedObject`.

For guidance on why tracked collections are preferred over replacing values
wholesale, see
[Root State](../reactivity/root-state/#toc_mutable-data-track-the-collection).


#### Arrays

Expand All @@ -362,6 +373,27 @@ class ShoppingList {
`trackedArray` supports all the normal native `Array` methods, ensuring that
their reads and writes are tracked.

#### Maps and Sets

`trackedMap`, `trackedSet`, `trackedWeakMap`, and `trackedWeakSet` round out
the collections, following the same pattern:

```js
import { trackedMap } from '@ember/reactive/collections';

class Cart {
quantities = trackedMap();

add(productId) {
let current = this.quantities.get(productId) ?? 0;
this.quantities.set(productId, current + 1);
}
}
```

Each collection supports all the methods of its native counterpart, ensuring
that their reads and writes are tracked.

## Caching of tracked properties

In contrast to computed properties from pre-Octane, tracked properties are not
Expand Down Expand Up @@ -403,7 +435,7 @@ getter is very expensive, however, you will want to cache the value and
retrieve it when the dependencies haven't changed. You want to recompute only
if a dependency has been updated.

Ember's [@cached decorator](https://api.emberjs.com/ember/6.8/functions/@glimmer%2Ftracking/cached) lets
Ember's [@cached decorator](https://api.emberjs.com/ember/release/functions/@glimmer%2Ftracking/cached) lets
you cache (or "memoize") a getter by simply marking it as `@cached`.

With this in mind, let's introduce caching to `aspectRatio`:
Expand Down Expand Up @@ -443,6 +475,10 @@ console.log(count); // 2
From the value of `count`, we see that, this time, `aspectRatio` was calculated
only twice.

In general, you should avoid using @cached unless you have confirmed that the getter you are decorating is computationally expensive, since @cached adds a small amount of overhead to the getter.
In general, you should avoid using `@cached` unless you have confirmed that
the getter you are decorating is computationally expensive, since `@cached`
adds a small amount of overhead to the getter. Beyond performance, there are
a couple of situations where caching changes behavior in useful ways - see
[Derived State](../reactivity/derived-state/#toc_caching) for details.

<!-- eof - needed for pages that end in a code block -->
Loading
Loading