Skip to content

Commit a80c79a

Browse files
authored
Rewrite createSelector reference docs for clarity (#965)
1 parent d36076b commit a80c79a

File tree

1 file changed

+37
-8
lines changed

1 file changed

+37
-8
lines changed

src/routes/reference/secondary-primitives/create-selector.mdx

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,27 +8,56 @@ import { createSelector } from "solid-js"
88
function createSelector<T, U>(
99
source: () => T,
1010
fn?: (a: U, b: T) => boolean
11-
): (k: U) => boolean
12-
11+
): (key: U) => boolean
1312
```
1413

15-
Creates a conditional signal that only notifies subscribers when entering or exiting their key matching the value.
16-
Useful for delegated selection state. As it makes the operation O(1) instead of O(n).
14+
Creates a parameterized derived boolean signal `selector(key)` that indicates
15+
whether `key` is equal to the current value of the `source` signal.
16+
These signals are optimized to notify each subscriber only when their `key`
17+
starts or stops matching the reactive `source` value
18+
(instead of every time `key` changes).
19+
If you have *n* different subscribers with different keys,
20+
and the `source` value changes from `a` to `b`, then
21+
instead of all *n* subscribers updating,
22+
at most two subscribers will update:
23+
the signal with key `a` will change to `false`,
24+
and the signal with key `b` will change to `true`.
25+
Thus it reduces from *n* updates to 2 updates.
26+
27+
Useful for defining the selection state of several selectable elements.
28+
For example:
1729

1830
```tsx
31+
const [selectedId, setSelectedId] = createSignal()
1932
const isSelected = createSelector(selectedId)
2033
2134
<For each={list()}>
2235
{(item) => <li classList={{ active: isSelected(item.id) }}>{item.name}</li>}
2336
</For>
2437
```
2538

26-
In the above code if the `item.id` is equal to the `selectedId` the `active` class will be added to the `li` element.
27-
If the `item.id` is not equal to the `selectedId` the `active` class will be removed from the `li` element.
39+
In the code above, each `li` element receives an `active` class
40+
exactly when the corresponding `item.id` is equal to `selectedId()`.
41+
When the `selectedId` signal changes, the `li` element(s) that previously
42+
had previously matching `id` get the `active` class removed, and the
43+
`li` element(s) that now have a matching `id` get the `active` class added.
44+
All other `li` elements get skipped, so if `id`s are distinct,
45+
only 2 DOM operations get performed.
46+
47+
By contrast, the following code would perform `list().length` DOM operations
48+
every time the `selectedId` signal changes:
49+
50+
```tsx
51+
const [selectedId, setSelectedId] = createSignal()
52+
53+
<For each={list()}>
54+
{(item) => <li classList={{ active: selectedId() === item.id }}>{item.name}</li>}
55+
</For>
56+
```
2857

2958
## Arguments
3059

3160
| Name | Type | Description |
3261
| :------- | :------------------------ | :------------------------------------------- |
33-
| `source` | `() => T` | The source signal to get the value from. |
34-
| `fn` | `(a: U, b: T) => boolean` | A function to compare the key and the value. |
62+
| `source` | `() => T` | The source signal to get the value from and compare with keys. |
63+
| `fn` | `(a: U, b: T) => boolean` | A function to compare the key and the value, returning whether they should be treated as equal. Default: `===` |

0 commit comments

Comments
 (0)