Skip to content

Instantly share code, notes, and snippets.

@Freak613
Last active February 1, 2020 07:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Freak613/715eb9d01a1ce0f017d70f63c3f22c39 to your computer and use it in GitHub Desktop.
Save Freak613/715eb9d01a1ce0f017d70f63c3f22c39 to your computer and use it in GitHub Desktop.
const createStore = () => {
let subscriptions = [];
let state;
let age = 0;
const getSubscriptions = () => subscriptions;
const getState = () => state;
const getAge = () => age;
const subscribe = fn => {
subscriptions = [...getSubscriptions(), fn];
return () => {
getSubscriptions().filter(v => v !== fn);
};
};
const publish = nextState => {
state = nextState;
age++;
subscriptions.forEach(fn => fn());
};
return {
getAge,
getState,
publish,
subscribe
};
}
const useStoreState = (mapState, equalityFn = (a, b) => a === b) => {
const store = useContext(StoreContext);
const storeAge = store.getAge();
const instanceRef = useRef({});
instanceRef.current.mapState = mapState;
instanceRef.current.equalityFn = equalityFn;
instanceRef.current.age = storeAge;
instanceRef.current.state = mapState(getState());
const [, forceRender] = useReducer(s => s + 1, 0);
useLayoutEffect(() => {
const checkMapState = () => {
const storeAge = store.getAge();
if (
instanceRef.current.age === storeAge ||
instanceRef.current.shutdown
) {
return;
}
const { mapState, equalityFn, state } = instanceRef.current;
const nextState = mapState(getState());
if (!equalityFn(state, nextState)) {
instanceRef.current.age = storeAge;
instanceRef.current.state = nextState;
forceRender();
}
};
const unsubscribe = subscribe(checkMapState);
return () => {
instanceRef.current.shutdown = true;
unsubscribe();
};
}, []);
return instanceRef.current.state;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment