React Hooks Modal

React Hooks Modal

Profile picture
👋
Developed and Written by: Donald Boulton🎉 0
|
2019-03-25
2 min read

React Hooks Modal

Taken from 🔗 janosh.io

🔥 Ready to start coding. But what to do first? One thing that seemed a good fit for hooks are modals. I’d implemented them once or twice before and in both cases came away with the feeling that a class component with all its boilerplate is overkill considering the tiny bit of state management required for modal functionality. As expected, using hooks I was able to boil it down quite considerably. This is what I ended up with.

What to do on a cold and wet January weekend? Why not check out the new React alpha (16.8). The one with Hooks as it’s come to be called.

All it took was a little skimming through 🔗 the docs, followed by updating react and react-dom.

install
bash
src/components/modal.tsx
tsx

And here are the styled components imported on line 3.

src/styled/style.tsx
tsx

As you can see, the styles are longer than the component itself. That’s where I spent most of my time too. Figuring out how to use React hooks took mere minutes. Props to the React team (pun intended) for the excellent onboarding experience!

Anyways, regarding usage, notice that the modal component doesn’t actually handle it’s own state. That’s done by the parent component. As an example here’s a 🔗 list of photos that when clicked enter a higher-resolution modal view.

src/components/modal.tsx
tsx

So basically just 4 lines of code to control the list of modals (and 2 of those do other things as well). I have to say, I was pretty impressed by that. For comparison, this is how much code the class implementation needed (just the JS, no styles yet).

src/components/toggle.tsx
tsx

Admittedly this component is bloated further by using Redux but even without it, it’s much harder to read and maintain. I’d call this use case a definite win for React Hooks!

Semantic HTML

One thing I should mention for future readers who want to use this Modal component: Once Chrome’s new 🔗<dialog> tag gets better browser support, it would improve semantics to use it for the modal container, i.e.

change
diff

and then maybe use the ::backdrop pseudo-element for the modal background.

Backdrop
diff

However, bear in mind that using ::backdrop would make it more difficult to close the modal on clicks outside of it, i.e. on the background. This is because React is unable to attach onClick event handlers to pseudo-elements and it seems unlikely this will change down the road. A workaround would be to use the new useRef and useEffect hook to create an event listener on the browser’s window object that checks for the target of the click event. That would complicate things a little, though, since the listener would have to trigger on all clicks and check that the modal doesn’t include the target before closing. Something like so:

src/components/modal.tsx
tsx

Keyboard controls

If you have a list of modals and you’d like users to be able to go to the next or previous modal using the arrow keys, you can add an event listener with the useEffect hook for this as well.

src/components/photos.tsx
tsx

The new styled components Next and Prev share most of their CSS with Close so it makes sense to reuse that:

src/styles/style.tsx
tsx

For the full and most up to date implementation of this component, check out 🔗 this site’s Github repo.