Skip to content

mpontus/react-modal-hook

Repository files navigation

react-modal-hook

NPM

Modal windows made easy with react hooks

Table of Contents

Install

npm install --save react-modal-hook

Usage

Use ModalProvider to provide modal context for your application:

import React from "react";
import ReactDOM from "react-dom";
import { ModalProvider } from "react-modal-hook";
import App from "./App";

ReactDOM.render(
  <ModalProvider>
    <App />
  </ModalProvider>,
  document.getElementById("root")
);

Call useModal to receive modal callbacks in your functional component:

import React from "react";
import { useModal } from "react-modal-hook";

const App = () => {
  const [showModal, hideModal] = useModal(() => (
    <div role="dialog" className="modal">
      <p>Modal content</p>
      <button onClick={hideModal}>Hide modal</button>
    </div>
  ));

  return <button onClick={showModal}>Show modal</button>;
};

Updating Modals

Second argument to useModals should contain an array of values referenced inside the modal:

const App = () => {
  const [count, setCount] = useState(0);
  const [showModal] = useModal(
    () => (
      <div role="dialog" className="modal">
        <span>The count is {count}</span>
        <button onClick={() => setCount(count + 1)}>Increment</button>
      </div>
    ),
    [count]
  );

  return <button onClick={showModal}>Show modal</button>;
};

Modals are also functional components and can use react hooks themselves:

const App = () => {
  const [showModal] = useModal(() => {
    const [count, setCount] = useState(0);

    return (
      <div role="dialog" className="modal">
        <span>The count is {count}</span>
        <button onClick={() => setCount(count + 1)}>Increment</button>
      </div>
    );
  });

  return <button onClick={showModal}>Show modal</button>;
};

Animated Modals

Use TransitionGroup as the modals container:

import React from "react";
import ReactDOM from "react-dom";
import { ModalProvider } from "react-modal-hook";
import { TransitionGroup } from "react-transition-group";
import App from "./App";

ReactDOM.render(
  <ModalProvider container={TransitionGroup}>
    <App />
  </ModalProvider>,
  document.getElementById("root")
);

When TransitionGroup detects of one of its children being removed, it will set its in prop to false, and wait for onExited callback to be called at the end of the animation.

You will receive those props in the function you pass to useModal and can translate them to the transition props of your modal component:

import React from "react";
import { useModal } from "react-modal-hook";
import { Button, Dialog, DialogActions, DialogTitle } from "@material-ui/core";

const App = () => {
  const [showModal, hideModal] = useModal(({ in: open, onExited }) => (
    <Dialog open={open} onExited={onExited}>
      <DialogTitle>Dialog Content</DialogTitle>
      <DialogActions>
        <Button onClick={hideModal}>Close</Button>
      </DialogActions>
    </Dialog>
  ));

  return <Button onClick={showModal}>Show modal</Button>;
};

License

MIT © mpontus