Skip to content

Commit c9cc183

Browse files
authored
Merge pull request #83 from bholmesdev/benh/variadic-select-args
Add docs for variadic select args
2 parents 63e3a57 + 125ae8f commit c9cc183

1 file changed

Lines changed: 25 additions & 5 deletions

File tree

www/src/content/docs/store.mdx

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { store } from "@simplestack/store";
1818
const documentStore = store({
1919
title: "Untitled",
2020
description: "Description",
21+
tags: [{ name: 'cooking' }],
2122
});
2223

2324
const title = documentStore.select("title");
@@ -29,6 +30,12 @@ description.set("New description");
2930
console.log(description.get()); // "New description"
3031
```
3132

33+
If you need to select a nested value, you can pass the complete object path as arguments to the `select()` function like so. This works for both object keys and array indices:
34+
35+
```tsx
36+
const tags = documentStore.select("meta", "tags");
37+
```
38+
3239
## Installation
3340

3441
Install the dependency from npm:
@@ -149,18 +156,27 @@ function setTheme(theme: string) {
149156

150157
However, this is fairly verbose and error-prone. Instead, you can create "sub-stores" by calling `select('key')` on the parent store, where `key` is the object key or array index you want to select. This creates a new store instance that lets you operate on the selected object key.
151158

152-
In this example, we can create a sub-store for the theme preference:
159+
In this example, we can create a sub-store for the `preference` key, and operate on the `theme` value:
153160

154-
```tsx ins={6}
161+
```tsx {6-7}
155162
const userStore = store({
156163
name: "Guest",
157164
preferences: { theme: "dark" },
158165
});
159166

160-
const themeStore = userStore.select("preferences").select("theme");
167+
const preferencesStore = userStore.select("preferences");
168+
const themeStore = preferencesStore.select("theme");
161169
```
162170

163-
Then, we can update the user's theme preference by calling `set()` on the sub-store directly:
171+
You can simplify this even further by passing the complete object path (`'preferences', 'theme'`) as arguments to the `select()` function:
172+
173+
```ts del={1-2} ins={3}
174+
const preferencesStore = userStore.select("preferences");
175+
const themeStore = preferencesStore.select("theme");
176+
const themeStore = userStore.select("preferences", "theme");
177+
```
178+
179+
Then, you can update the user's theme preference by calling `set()` on the sub-store directly:
164180

165181
```tsx ins={6} del={2-5}
166182
function setTheme(theme: string) {
@@ -174,6 +190,10 @@ function setTheme(theme: string) {
174190

175191
Changes to `themeStore` automatically update `userStore`, and vice versa.
176192

193+
:::info
194+
If a `select()` path crosses a potentially undefined value at runtime (for example, `preferences` is missing), `set()` is discarded for safety and a warning is logged in dev mode.
195+
:::
196+
177197
You can then subscribe to a sub-store the same way you subscribe to a parent store. Pass the sub-store to the `useStoreValue` hook:
178198

179199
<Tabs syncKey="framework">
@@ -385,5 +405,5 @@ These types are exported for TypeScript users.
385405
- `get(): T` - Get the current value of the store.
386406
- `set(setter: Setter<T>): void` - Set the value directly or by using a function that receives the current state.
387407
- `subscribe(callback: (state: T) => void): () => void` - Subscribe with a callback. Returns an unsubscribe function.
388-
- `select(key: K): Store<SelectValue<T, K>>` (present only when `T` is an object or array) - Select a key or array index of the store. Returns a nested Store.
408+
- `select(...path: (string | number | symbol)[]): Store<...>` (present only when `T` is an object or array) - Select one or more keys/indices. Returns a nested Store (type inferred from the path).
389409
- `getInitial(): T` - Get the initial state the store was created with. Used internally for SSR resume-ability.

0 commit comments

Comments
 (0)