UNPKG

@react-navigation/core

Version:

Core utilities for building navigators

87 lines (86 loc) 3.87 kB
import { nanoid } from 'nanoid/non-secure'; import * as React from 'react'; import useLatestCallback from 'use-latest-callback'; import NavigationHelpersContext from './NavigationHelpersContext'; import NavigationRouteContext from './NavigationRouteContext'; import PreventRemoveContext from './PreventRemoveContext'; /** * Util function to transform map of prevented routes to a simpler object. */ const transformPreventedRoutes = preventedRoutesMap => { const preventedRoutesToTransform = [...preventedRoutesMap.values()]; const preventedRoutes = preventedRoutesToTransform.reduce((acc, _ref) => { var _acc$routeKey; let { routeKey, preventRemove } = _ref; acc[routeKey] = { preventRemove: ((_acc$routeKey = acc[routeKey]) === null || _acc$routeKey === void 0 ? void 0 : _acc$routeKey.preventRemove) || preventRemove }; return acc; }, {}); return preventedRoutes; }; /** * Component used for managing which routes have to be prevented from removal in native-stack. */ export default function PreventRemoveProvider(_ref2) { let { children } = _ref2; const [parentId] = React.useState(() => nanoid()); const [preventedRoutesMap, setPreventedRoutesMap] = React.useState(new Map()); const navigation = React.useContext(NavigationHelpersContext); const route = React.useContext(NavigationRouteContext); const preventRemoveContextValue = React.useContext(PreventRemoveContext); // take `setPreventRemove` from parent context - if exist it means we're in a nested context const setParentPrevented = preventRemoveContextValue === null || preventRemoveContextValue === void 0 ? void 0 : preventRemoveContextValue.setPreventRemove; const setPreventRemove = useLatestCallback((id, routeKey, preventRemove) => { if (preventRemove && (navigation == null || navigation !== null && navigation !== void 0 && navigation.getState().routes.every(route => route.key !== routeKey))) { throw new Error(`Couldn't find a route with the key ${routeKey}. Is your component inside NavigationContent?`); } setPreventedRoutesMap(prevPrevented => { var _prevPrevented$get, _prevPrevented$get2; // values haven't changed - do nothing if (routeKey === ((_prevPrevented$get = prevPrevented.get(id)) === null || _prevPrevented$get === void 0 ? void 0 : _prevPrevented$get.routeKey) && preventRemove === ((_prevPrevented$get2 = prevPrevented.get(id)) === null || _prevPrevented$get2 === void 0 ? void 0 : _prevPrevented$get2.preventRemove)) { return prevPrevented; } const nextPrevented = new Map(prevPrevented); if (preventRemove) { nextPrevented.set(id, { routeKey, preventRemove }); } else { nextPrevented.delete(id); } return nextPrevented; }); }); const isPrevented = [...preventedRoutesMap.values()].some(_ref3 => { let { preventRemove } = _ref3; return preventRemove; }); React.useEffect(() => { if ((route === null || route === void 0 ? void 0 : route.key) !== undefined && setParentPrevented !== undefined) { // when route is defined (and setParentPrevented) it means we're in a nested stack // route.key then will be the route key of parent setParentPrevented(parentId, route.key, isPrevented); return () => { setParentPrevented(parentId, route.key, false); }; } return; }, [parentId, isPrevented, route === null || route === void 0 ? void 0 : route.key, setParentPrevented]); const value = React.useMemo(() => ({ setPreventRemove, preventedRoutes: transformPreventedRoutes(preventedRoutesMap) }), [setPreventRemove, preventedRoutesMap]); return /*#__PURE__*/React.createElement(PreventRemoveContext.Provider, { value: value }, children); } //# sourceMappingURL=PreventRemoveProvider.js.map