generated from adamrybinski/haunted-snow
-
Notifications
You must be signed in to change notification settings - Fork 1
/
useSelector.js
28 lines (24 loc) · 1012 Bytes
/
useSelector.js
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
import { useEffect, useRef, useState } from './deps.js';
import { isActorWithState } from './useActor.js';
const defaultCompare = (a, b) => a === b;
const defaultGetSnapshot = a => isActorWithState(a) ? a.state : undefined;
export function useSelector(actor, selector, compare = defaultCompare, getSnapshot = defaultGetSnapshot) {
const [selected, setSelected] = useState(() => selector(getSnapshot(actor)));
const selectedRef = useRef(selected);
useEffect(() => {
const updateSelectedIfChanged = nextSelected => {
if (!compare(selectedRef.current, nextSelected)) {
setSelected(nextSelected);
selectedRef.current = nextSelected;
}
};
const initialSelected = selector(getSnapshot(actor));
updateSelectedIfChanged(initialSelected);
const sub = actor.subscribe(emitted => {
const nextSelected = selector(emitted);
updateSelectedIfChanged(nextSelected);
});
return () => sub.unsubscribe();
}, [selector, compare]);
return selected;
}