Here is a simplified version of ModalConductor.jsx.

You can see the concept is dead simple (barely worth a blog post).

Let’s see what one of the modal components looks like. (Note that these examples are missing styling to keep things simple.)

This is kinda simple in principle. Note that the top level of the returned DOM is a component called ModalWrapper which describes the modally parts of the modal, while SignIn.jsx defines what goes inside the modal (in this case, one <p> and three <button>s). SignIn.jsx also sends some properties into the ModalWrapper such as the title and width. Other modals might pass down a callback to handle the user clicking OK.

If you’re new to React this might be a little mind bending at first. The ModalWrapper component is a child of SignIn, but when the DOM is rendered, it’s a parent of the sign in content because SignIn passes those elements in as children of the ModalWrapper component.

The end result:

Now let’s look at a simplified version of the ModalWrapper component.

If we look at the the DOM being returned we can see that it handles the wrapper and the header and the close buttons, and injects {props.children} right in the middle. It also handles clicking on the background (the black backdrop) to close the modal.

This last part might raise the question “where does the hideModal method come from?”

A tremendous question. Let’s go back to the first component: ModalConductor.jsx — because in addition to deciding which modal to render, it also connects to the store and sends in all my actions (I’m using Redux).

If the idea of sending down the whole store to all modals makes you a little queasy and you want to add some complexity to your app, you could add a ‘container’ component for each of your modals. (At some point I will mount my campaign to have them renamed from ‘container’ components to ‘connector’ components, but since this one decides which modal to show I’m sticking with ‘conductor’).

The setup is all fairly simple but is powerful nonetheless. For example if you want to disable the OK button when some condition is met, you can just down a ‘disableButton’ prop. For example, in Malla you can define the ID for a text field. This becomes the property name in the JSON that the API returns, so must match a pattern. If the ID isn’t valid, the user should not be able to save.