use-modal-react v1.0.0
React Use Modal
react-use-modal is a hook meant to take care of state management for modals, instead of requiring you to do so. This library does not provide a component for rendering modals, but it allows you to choose what components to use.
Table of Content
Context - Without react-use-modal
Consider the following example:
function MyModalComponent(props) {
    const [isOpen, setIsOpen] = useState(false);
    return (
        <>
            <Button onClick={() => setIsOpen(true)}>
                Open Modal
            </Button>
            <Modal isOpen={isOpen} onHide={() => setIsOpen(false)}>
                <ModalContents/>
            </Modal>
        </>
    );
}What's bad about this is that in every component we need a modal, we will have to: 1. create a state for the modal opening 2. render the actual modal content alongside the rest of the components tree
Basic Usage - With react-use-modal
First things first, we want to make sure the modal context is available, so add the ModalProvider somewhere up the tree (like your main.js):
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
        <ModalProvider variants={Modal}>
            <App/>
        </ModalProvider>
    </React.StrictMode>
);The
variantsprop is the component used to actually render the Modal. Read the API description.
The example above could be written as:
function MyModalComponent(props) {
    const openModal = useModal(ModalContents);
    return (
        <Button onClick={openModal}>
            Open Modal
        </Button>
    );
}The
useModalhook is fairly customizable. Read the API description.
API
1. ModalProvider component
The provider of the Modal Context. This library cannot be used without this.
| Property Name | Accepted Types | Description | 
|---|---|---|
| variants | Component \| Object | All possible variants of modals. | 
2. useModal(useComponent: Component, options?: HookProps, deps = []): OpenModalFn
The actual hook responsible with the magic. It accepts 3 parameters.
| Parameter Name | Accepted Types | Description | 
|---|---|---|
| useComponent | Component | The component rendered as modal content. | 
| options(optional) | HookProps | Additional options for modal customization (check table below). | 
| deps(optional) | Array | React dependency array. There aren't really many usecases for using this.Default value: [] | 
3. Additional options accepted by the useModal hook:
| Property Name | Accepted Types | Description | 
|---|---|---|
| variant(optional) | string | The modal variant to be used. Must be one of the specified variants.Default value: default | 
| isDefaultOpen(optional) | boolean | Controls whether the modal should be opened by default or not.Default value: false | 
| onHide(optional) | (params: any) => any | Function called when the modal is closed. Accepts one parameter. | 
| props(optional) | Object | Properties passed to the Modal variant rendered. | 
| componentProps(optional) | Object | Properties passed to the component rendered inside the modal. | 
4. Return: OpenModalFn: (params: IDynamicParams) => any
A function that opens the modal when called. It accepts one parameter of type
Objectthat will be used as theparamsprop of the modal content component.
Example Usages
1. Custom Modal Variant & Props
import Modal from '/my-components/modals/Modal';
import RedModalVariant from '/my-components/modals/RedModalVariant';
// variants used in ModalProvider
const variants = {
    default: Modal,
    'red-modal': RedModalVariant,
};
// MyComponent.js
function MyComponent() {
    const openModal = useModal(ModalContentComponent, {
        variant: 'red-modal',
        props: {    // will be passed to the RedModalVariant component
            size: 'lg',     
        },
        componentProps: {   // will be passed to the ModalContentComponent
            content: 'hello world',     
        },
    });
    return (
        <button onClick={openModal}>
            Open Modal
        </button>
    );
}2. Dynamic Content
When you have a list of items, instead of rendering a modal for all of the items (hence, managing multiple component states), you can do something like this:
// MyComponent.js
function MyComponent() {
    const [list, setList] = useState([]);
    useEffect(fetchMyList, []);
    const openModal = useModal(EditListItemModal, {
        componentProps: {
            title: 'Edit Item',
        },
    });
    return (
        <ul>
            {list.map(item => (
                <li key={item.id} onClick={() => openModal(item)} />
            ))}
        </ul>
    );
}
// EditListItemModal.js
function EditListItemModal({ title, params: item }) {
    // the dynamic params prop will be the item passed when openModal got called
    // title, however, is a static prop passed when the modal is initialized
}This way, you can use the same modal instance, while only changing the data used to render the content.
3 years ago