UNPKG

ionic-rocketjump

Version:
151 lines (122 loc) 4.64 kB
import { useRef, useState, useCallback, useEffect, useMemo } from 'react'; import { getRunValuesFromDeps, shouldRunDeps, getMetaFromDeps } from 'rocketjump-core'; import { useIonViewDidEnter, useIonViewDidLeave } from '@ionic/react'; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } var DefaultConfig = { cleanOnNewEffect: true, runOnEnter: true, cleanOnLeave: false }; function createUseIonRunRj(useRj) { return function useIonRunRj(rjObject, runArgs, rawConfig) { if (runArgs === void 0) { runArgs = []; } // Normalize config support 4 original shouldCleanOnNewEffect boolean param var config; if (typeof config === 'boolean') { config = _extends({}, DefaultConfig, { cleanOnNewEffect: rawConfig }); } else { config = _extends({}, DefaultConfig, {}, rawConfig); } // Expand config var shouldCleanOnNewEffect = config.cleanOnNewEffect; var shouldRunOnEnter = config.runOnEnter; var shouldCleanOnLeave = config.cleanOnLeave; var didMount = useRef(false); for (var _len = arguments.length, params = new Array(_len > 3 ? _len - 3 : 0), _key = 3; _key < _len; _key++) { params[_key - 3] = arguments[_key]; } var _useRj = useRj.apply(void 0, [rjObject].concat(params)), state = _useRj[0], originalActions = _useRj[1]; var run = originalActions.run, clean = originalActions.clean; var _useState = useState({}), withMeta = _useState[0], setWithMeta = _useState[1]; var prevWithMeta = useRef(null); var runValues = getRunValuesFromDeps(runArgs); var prevRunValues = useRef(null); var maybePerformRun = useCallback(function () { var shouldRun = shouldRunDeps(runArgs); if (shouldRun) { var _run$withMeta; var meta = getMetaFromDeps(runArgs, prevRunValues.current); // Add meta only if setWithMeta in called along with last args update var hackRunWithMeta = {}; if (prevWithMeta.current && prevWithMeta.current !== withMeta) { hackRunWithMeta = withMeta; } (_run$withMeta = run.withMeta(_extends({}, meta, {}, hackRunWithMeta))).run.apply(_run$withMeta, runValues); } prevRunValues.current = runValues; prevWithMeta.current = withMeta; // spreading run arguments as deps means: // every time a run arguments changes (Object.is comparison) // a run is triggered and (if configured) a clean to clean up // the old effect related state // eslint-disable-next-line react-hooks/exhaustive-deps }, [clean, run, shouldRunOnEnter, shouldCleanOnNewEffect].concat(runValues)); // NOTE: cause useIonViewDidEnter didn't handle // a clean callback as useEffect does we do this // to trigger clean effect on subsequent values changes var _useState2 = useState(false), cleanNextTime = _useState2[0], setNextClean = _useState2[1]; useIonViewDidEnter(function () { if (shouldRunOnEnter) { maybePerformRun(); if (shouldCleanOnNewEffect && !cleanNextTime) { setNextClean(true); } } }); useIonViewDidLeave(function () { if (shouldCleanOnLeave) { clean(); } }); useEffect(function () { if (shouldRunOnEnter && !didMount.current) { return; } var shouldRun = shouldRunDeps(runArgs); return function () { if (shouldCleanOnNewEffect && shouldRun) { clean(); } }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [shouldCleanOnNewEffect, shouldRunOnEnter, cleanNextTime].concat(runValues)); // Trigger run on run values changes useEffect(function () { if (!didMount.current) { // Now is MOUNTED! didMount.current = true; // The first run will triggered by useIonViewDidEnter if (shouldRunOnEnter) { return; } } maybePerformRun(); }, [shouldRunOnEnter, maybePerformRun]); var actions = useMemo(function () { return _extends({}, originalActions, { withNextMeta: setWithMeta }); }, [setWithMeta, originalActions]); return useMemo(function () { return [state, actions]; }, [state, actions]); }; } export { createUseIonRunRj as c };