1. # use-subscription
    
  2. 
    
  3. React Hook for subscribing to external data sources.
    
  4. 
    
  5. **You may now migrate to [`use-sync-external-store`](https://www.npmjs.com/package/use-sync-external-store) directly instead, which has the same API as [`React.useSyncExternalStore`](https://react.dev/reference/react/useSyncExternalStore). The `use-subscription` package is now a thin wrapper over `use-sync-external-store` and will not be updated further.**
    
  6. 
    
  7. # Installation
    
  8. 
    
  9. ```sh
    
  10. # Yarn
    
  11. yarn add use-subscription
    
  12. 
    
  13. # NPM
    
  14. npm install use-subscription
    
  15. ```
    
  16. 
    
  17. # Usage
    
  18. 
    
  19. To configure a subscription, you must provide two methods: `getCurrentValue` and `subscribe`.
    
  20. 
    
  21. In order to avoid removing and re-adding subscriptions each time this hook is called, the parameters passed to this hook should be memoized. This can be done by wrapping the entire subscription with `useMemo()`, or by wrapping the individual callbacks with `useCallback()`.
    
  22. 
    
  23. ## Subscribing to event dispatchers
    
  24. 
    
  25. Below is an example showing how `use-subscription` can be used to subscribe to event dispatchers such as DOM elements.
    
  26. 
    
  27. ```js
    
  28. import React, { useMemo } from "react";
    
  29. import { useSubscription } from "use-subscription";
    
  30. 
    
  31. // In this example, "input" is an event dispatcher (e.g. an HTMLInputElement)
    
  32. // but it could be anything that emits an event and has a readable current value.
    
  33. function Example({ input }) {
    
  34. 
    
  35.   // Memoize to avoid removing and re-adding subscriptions each time this hook is called.
    
  36.   const subscription = useMemo(
    
  37.     () => ({
    
  38.       getCurrentValue: () => input.value,
    
  39.       subscribe: callback => {
    
  40.         input.addEventListener("change", callback);
    
  41.         return () => input.removeEventListener("change", callback);
    
  42.       }
    
  43.     }),
    
  44. 
    
  45.     // Re-subscribe any time our input changes
    
  46.     // (e.g. we get a new HTMLInputElement prop to subscribe to)
    
  47.     [input]
    
  48.   );
    
  49. 
    
  50.   // The value returned by this hook reflects the input's current value.
    
  51.   // Our component will automatically be re-rendered when that value changes.
    
  52.   const value = useSubscription(subscription);
    
  53. 
    
  54.   // Your rendered output goes here ...
    
  55. }
    
  56. ```
    
  57. 
    
  58. ## Subscribing to observables
    
  59. 
    
  60. Below are examples showing how `use-subscription` can be used to subscribe to certain types of observables (e.g. RxJS `BehaviorSubject` and `ReplaySubject`).
    
  61. 
    
  62. **Note** that it is not possible to support all observable types (e.g. RxJS `Subject` or `Observable`) because some provide no way to read the "current" value after it has been emitted.
    
  63. 
    
  64. ### `BehaviorSubject`
    
  65. ```js
    
  66. const subscription = useMemo(
    
  67.   () => ({
    
  68.     getCurrentValue: () => behaviorSubject.getValue(),
    
  69.     subscribe: callback => {
    
  70.       const subscription = behaviorSubject.subscribe(callback);
    
  71.       return () => subscription.unsubscribe();
    
  72.     }
    
  73.   }),
    
  74. 
    
  75.   // Re-subscribe any time the behaviorSubject changes
    
  76.   [behaviorSubject]
    
  77. );
    
  78. 
    
  79. const value = useSubscription(subscription);
    
  80. ```
    
  81. 
    
  82. ### `ReplaySubject`
    
  83. ```js
    
  84. const subscription = useMemo(
    
  85.   () => ({
    
  86.     getCurrentValue: () => {
    
  87.       let currentValue;
    
  88.       // ReplaySubject does not have a sync data getter,
    
  89.       // So we need to temporarily subscribe to retrieve the most recent value.
    
  90.       replaySubject
    
  91.         .subscribe(value => {
    
  92.           currentValue = value;
    
  93.         })
    
  94.         .unsubscribe();
    
  95.       return currentValue;
    
  96.     },
    
  97.     subscribe: callback => {
    
  98.       const subscription = replaySubject.subscribe(callback);
    
  99.       return () => subscription.unsubscribe();
    
  100.     }
    
  101.   }),
    
  102. 
    
  103.   // Re-subscribe any time the replaySubject changes
    
  104.   [replaySubject]
    
  105. );
    
  106. 
    
  107. const value = useSubscription(subscription);
    
  108. ```