Selectors
Efficiently subscribing to state slices in @ilokesto/state.
Selectors
Selectors are the primary mechanism for reading state in @ilokesto/state. They allow components to subscribe only to the specific data they need, which is crucial for maintaining performance in larger applications.
Basic Usage
The hook returned by create accepts a selector function as its first argument.
const [count, setCount] = useCounter(state => state.count);The hook returns a tuple where:
- The first element is the selected value.
- The second element is the writer (
setStateordispatch). In state mode it still writes the full store state, even if the selector returned only one slice.
Subscription Logic
When you use a selector, the component only re-renders when the result of that selector changes.
// This component only re-renders when state.user.name changes.
const [name] = useUserStore(state => state.user.name);If you call the hook without a selector, the component subscribes to the entire store and re-renders on every state change.
// Subscribes to EVERYTHING. Use with caution.
const [state, setState] = useStore();Memoization and Comparison
@ilokesto/state memoizes through the store snapshot path rather than through a custom selector equality API.
- Primitives still behave as you would expect.
- Objects and arrays can reuse previous selected values when the underlying store snapshots remain deeply equal.
Derived State
You can use selectors to compute derived state directly.
const [isEven] = useCounter(state => state.count % 2 === 0);This is efficient because the calculation only happens during the store update cycle, and the component only re-renders if the boolean result changes.
Best Practices
- Keep Selectors Simple: Selectors should be pure functions. Avoid complex logic inside them.
- Granular Subscriptions: Prefer selecting specific fields instead of large objects to minimize re-renders.
- Stable References: If you define selectors outside of your components, you can ensure they have stable references.