react-native-use-modal-hooks
Version:
React hooks for displaying a modal window in React Native
53 lines (52 loc) • 1.95 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useModal = void 0;
const react_1 = require("react");
const ModalContext_1 = require("./ModalContext");
/**
* Utility function to generate unique number per component instance
*/
const generateModalKey = (() => {
let count = 0;
return () => `${++count}`;
})();
/**
* Check whether the argument is a stateless component.
*
* We take advantage of the stateless nature of functional components to be
* inline the rendering of the modal component as part of another immutable
* component.
*
* This is necessary for allowing the modal to update based on the inputs passed
* as the second argument to useModal without unmounting the previous version of
* the modal component.
*/
const isFunctionalComponent = (Component) => {
const prototype = Component.prototype;
return !prototype || !prototype.isReactComponent;
};
/**
* React hook for showing modal windows
*/
exports.useModal = (component, inputs = []) => {
if (!isFunctionalComponent(component)) {
throw new Error("Only stateless components can be used as an argument to useModal. You have probably passed a class component where a function was expected.");
}
const key = react_1.useMemo(generateModalKey, []);
const modal = react_1.useMemo(() => component, inputs);
const context = react_1.useContext(ModalContext_1.ModalContext);
const [isShown, setShown] = react_1.useState(false);
const showModal = react_1.useCallback(() => setShown(true), []);
const hideModal = react_1.useCallback(() => setShown(false), []);
react_1.useEffect(() => {
if (isShown) {
context.showModal(key, modal);
}
else {
context.hideModal(key);
}
// Hide modal when parent component unmounts
return () => context.hideModal(key);
}, [modal, isShown]);
return [showModal, hideModal];
};