You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: www/src/content/docs/store.mdx
+82-16Lines changed: 82 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -213,6 +213,16 @@ You can then subscribe to a sub-store the same way you subscribe to a parent sto
213
213
</TabItem>
214
214
</Tabs>
215
215
216
+
:::tip
217
+
`useStoreValue` also accepts a selector function for dynamic keys or computed values:
218
+
219
+
```tsx
220
+
const title =useStoreValue(documentStore, (s) =>s.notes[id]?.title);
221
+
```
222
+
223
+
[📚 See the API reference to learn more.](#usestorevaluestore-selector)
224
+
:::
225
+
216
226
## Next.js support
217
227
218
228
Simple store is compatible with Next.js, and is built to handle server-side rendering and client-side hydration gracefully.
@@ -280,12 +290,14 @@ const title = doc.select("title");
280
290
281
291
### React
282
292
283
-
#### useStoreValue(store)
293
+
#### useStoreValue(store, selector?)
284
294
285
-
React hook to subscribe to a store and get its current value.
295
+
React hook to subscribe to a store and get its current value. Optionally pass a selector function to derive a value from the store.
286
296
287
-
- Parameters: `store: Store<T> | undefined`
288
-
- Returns: `T | undefined`
297
+
- Parameters:
298
+
-`store: Store<T> | undefined`
299
+
-`selector?: (state: T) => R` - optional function to select/compute a value
300
+
- Returns: `R | T | undefined`
289
301
290
302
```tsx
291
303
import { store } from"@simplestack/store";
@@ -301,6 +313,67 @@ function Counter() {
301
313
}
302
314
```
303
315
316
+
With a selector:
317
+
318
+
```tsx
319
+
const documentStore =store({
320
+
notes: {
321
+
"1": { title: "First" },
322
+
"2": { title: "Second" },
323
+
},
324
+
});
325
+
326
+
function NoteTitle({ id }: { id:string }) {
327
+
// Only re-renders when this specific note's title changes
328
+
const title =useStoreValue(documentStore, (s) =>s.notes[id]?.title);
329
+
return <h1>{title}</h1>;
330
+
}
331
+
332
+
function NoteCount() {
333
+
// Compute derived values inline
334
+
const count =useStoreValue(documentStore, (s) =>Object.keys(s.notes).length);
335
+
return <span>{count} notes</span>;
336
+
}
337
+
```
338
+
339
+
#### useShallow(selector)
340
+
341
+
Wraps a selector with shallow equality comparison. Use this when your selector returns a new array or object reference on each call.
342
+
343
+
**The problem:** selectors that return new references (like `Object.values()`, array `filter()`, or object spreads) cause infinite re-renders because React sees a "new" value each time.
-`select(key: K): Store<SelectValue<T, K>>`: present only when `T` is an object or array
316
-
317
-
## Contributing
318
-
319
-
Contributions are welcome! Please feel free to submit an issue or pull request.
320
-
321
-
## License
322
-
323
-
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
385
+
-`get(): T` - Get the current value of the store.
386
+
-`set(setter: Setter<T>): void` - Set the value directly or by using a function that receives the current state.
387
+
-`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.
389
+
-`getInitial(): T` - Get the initial state the store was created with. Used internally for SSR resume-ability.
0 commit comments