From 984b045cedc2c5f6e4466d190de6dfdfe7f3463d Mon Sep 17 00:00:00 2001 From: NikolaBorislavovHristov Date: Thu, 5 Dec 2019 16:16:58 +0200 Subject: [PATCH] generic useModelState hook implemented --- src/common/index.js | 2 ++ src/common/useModelState.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/common/useModelState.js diff --git a/src/common/index.js b/src/common/index.js index f8052ba47..e1d2437a8 100644 --- a/src/common/index.js +++ b/src/common/index.js @@ -23,6 +23,7 @@ const useFullscreen = require('./useFullscreen'); const useInLibrary = require('./useInLibrary'); const useLiveRef = require('./useLiveRef'); const useLocationHash = require('./useLocationHash'); +const useModelState = require('./useModelState'); const useRouteActive = require('./useRouteActive'); const useSpreadState = require('./useSpreadState'); const useUser = require('./useUser'); @@ -53,6 +54,7 @@ module.exports = { useInLibrary, useLiveRef, useLocationHash, + useModelState, useRouteActive, useSpreadState, useUser diff --git a/src/common/useModelState.js b/src/common/useModelState.js new file mode 100644 index 000000000..3393bbbd2 --- /dev/null +++ b/src/common/useModelState.js @@ -0,0 +1,32 @@ +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 useModelState = ({ model, action, timeout, map, init }) => { + const modelRef = React.useRef(model); + const { core } = useServices(); + const routeFocused = useRouteFocused(); + const [state, setState] = useDeepEqualState(init); + React.useLayoutEffect(() => { + core.dispatch(action, modelRef.current); + }, [action]); + React.useLayoutEffect(() => { + const onNewState = throttle(() => { + const state = core.getState(modelRef.current); + setState(typeof map === 'function' ? map(state) : state); + }, timeout); + if (routeFocused) { + core.on('NewState', onNewState); + onNewState.call(); + } + return () => { + onNewState.cancel(); + core.off('NewState', onNewState); + }; + }, [routeFocused]); + return state; +}; + +module.exports = useModelState;