use-behavior.ts 997 B

1234567891011121314151617181920212223242526272829303132333435363738
  1. /**
  2. * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author David Sehnal <david.sehnal@gmail.com>
  5. */
  6. import { useEffect, useState } from 'react';
  7. interface Behavior<T> {
  8. value: T;
  9. subscribe(f: (v: T) => void): { unsubscribe(): void };
  10. }
  11. export function useBehavior<T>(s: Behavior<T>): T;
  12. // eslint-disable-next-line
  13. export function useBehavior<T>(s: Behavior<T> | undefined): T | undefined;
  14. // eslint-disable-next-line
  15. export function useBehavior<T>(s: Behavior<T> | undefined): T | undefined {
  16. const [value, setValue] = useState(s?.value);
  17. useEffect(() => {
  18. if (!s) return;
  19. let fst = true;
  20. const sub = s.subscribe((v) => {
  21. if (fst) {
  22. fst = false;
  23. if (v !== value) setValue(v);
  24. } else setValue(v);
  25. });
  26. return () => {
  27. sub.unsubscribe();
  28. };
  29. // eslint-disable-next-line
  30. }, [s]);
  31. return value;
  32. }