useLegacyStore.tsx 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import {useEffect, useRef, useState} from 'react';
  2. import type {Store} from 'reflux';
  3. import type {CommonStoreDefinition} from './types';
  4. interface LegacyStoreShape extends Store, CommonStoreDefinition<any> {}
  5. /**
  6. * Returns the state of a reflux store. Automatically unsubscribes when destroyed
  7. *
  8. * ```
  9. * const teams = useLegacyStore(TeamStore);
  10. * ```
  11. */
  12. export function useLegacyStore<T extends LegacyStoreShape>(
  13. store: T
  14. ): ReturnType<T['getState']> {
  15. const [state, setState] = useState(store.getState());
  16. // Not all stores emit the new state, call get on change
  17. const callback = () => setState(store.getState());
  18. // If we setup the listener in useEffect, there is a small race condition
  19. // where the store may emit an event before we're listening (since useEffect
  20. // fires AFTER rendering). Avoid this by ensuring we start listening
  21. // *immediately* after we initialize the useState.
  22. const unlisten = useRef<Function>();
  23. if (unlisten.current === undefined) {
  24. unlisten.current = store.listen(callback, undefined);
  25. }
  26. useEffect(() => {
  27. return () => void unlisten.current?.();
  28. }, []);
  29. return state;
  30. }