mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-12 19:31:55 +00:00
62 lines
2.1 KiB
JavaScript
62 lines
2.1 KiB
JavaScript
const React = require('react');
|
|
const throttle = require('lodash.throttle');
|
|
const { useRouteFocused } = require('stremio-router');
|
|
const { useServices } = require('stremio/services');
|
|
const useDeepEqualState = require('stremio/common/useDeepEqualState');
|
|
|
|
const UNLOAD_ACTION = {
|
|
action: 'Unload',
|
|
};
|
|
|
|
const useModelState = ({ model, init, action, timeout, onNewState, map, mapWithCtx }) => {
|
|
const modelRef = React.useRef(model);
|
|
const mountedRef = React.useRef(false);
|
|
const { core } = useServices();
|
|
const routeFocused = useRouteFocused();
|
|
const [state, setState] = useDeepEqualState(init);
|
|
React.useLayoutEffect(() => {
|
|
core.dispatch(action, modelRef.current);
|
|
}, [action]);
|
|
React.useLayoutEffect(() => {
|
|
return () => {
|
|
core.dispatch(UNLOAD_ACTION, modelRef.current);
|
|
};
|
|
}, []);
|
|
React.useLayoutEffect(() => {
|
|
const onNewStateThrottled = throttle(() => {
|
|
const state = core.getState(modelRef.current);
|
|
if (typeof onNewState === 'function') {
|
|
const action = onNewState(state);
|
|
const handled = core.dispatch(action, modelRef.current);
|
|
if (handled) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (typeof mapWithCtx === 'function') {
|
|
const ctx = core.getState('ctx');
|
|
setState(mapWithCtx(state, ctx));
|
|
} else if (typeof map === 'function') {
|
|
setState(map(state));
|
|
} else {
|
|
setState(state);
|
|
}
|
|
}, timeout);
|
|
if (routeFocused) {
|
|
core.on('NewState', onNewStateThrottled);
|
|
if (mountedRef.current) {
|
|
onNewStateThrottled.call();
|
|
}
|
|
}
|
|
return () => {
|
|
onNewStateThrottled.cancel();
|
|
core.off('NewState', onNewStateThrottled);
|
|
};
|
|
}, [routeFocused, timeout, onNewState, map, mapWithCtx]);
|
|
React.useLayoutEffect(() => {
|
|
mountedRef.current = true;
|
|
}, []);
|
|
return state;
|
|
};
|
|
|
|
module.exports = useModelState;
|