All files / src/hooks/useSelector useSelector.ts

100% Statements 4/4
100% Branches 0/0
100% Functions 1/1
100% Lines 4/4

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 485x     5x                                                                           5x 44x          
import { useSyncExternalStore } from 'react'
import type { Reaction } from 'watch-state'
 
import { subscribe } from '../../utils'
 
/**
 * A function that selects or derives a value from the current state.
 * @template T The type of the selected value
 */
export type Selector<T> = Reaction<T>
 
/**
 * React hook to select a portion of state or derive data from the current state.
 *
 * @description
 * Uses `useSyncExternalStore` for correct synchronization of external stores with React.
 * Automatically subscribes via `Watch` and unsubscribes on unmount.
 * React automatically optimizes re-renders — component only updates when the selected value actually changes
 * (compared using `Object.is`).
 *
 * @example
 * ```ts
 * const $user = new State({ name: 'Alice', age: 30 })
 *
 * const UserProfile = () => {
 *   const name = useSelector(() => $user.value.name)
 *   const isAdult = useSelector(() => $user.value.age >= 18)
 *
 *   return (
 *     <div>
 *       <h1>{name}</h1>
 *       <p>Adult: {isAdult ? 'Yes' : 'No'}</p>
 *     </div>
 *   )
 * }
 * ```
 *
 * @param selector - A function that selects or derives a value from the current state.
 * @returns The selected or derived value. Re-render occurs only when the value actually changes.
 * @template T The type of the selected value
 */
export function useSelector<T> (selector: Selector<T>): T {
  return useSyncExternalStore(
    subscribe,
    selector,
  )
}