Integrating semantic-ui modal with React and Redux
Lets integrate Redux into your React Ecosystem
We've all used modals sometime in our lives, right?
In the past few days I've been studying React and Redux with a simple CRUD application, and had the need to show a confirmation modal to my user.
Since I was using the excellent semantic-ui-react, I already had access to the Confirm component, that shows a modal confirmation and was quite easy to use, in theory. I didn't want each of my components to have a reference to the library, and I especially didn't want to manage the modal state inside my stateless components.
So, since I was already using Redux to manage state, why not use it to manage my modals and its states? That's what we're gonna do in this post.
A simplest exapmle of React-Redux
Step 1: Setup our sample application
Let's begin by setting up our application with create-react-app. If you're not familiar with this tool, take your time to go through their README, it's quite good. First, let's install create-react-app and scaffold our application:
npm i -g create-react-app
create-react-app semantic-ui-modal-redux
The tool created all the needed files and configurations for us, so now we just have to setup our dependencies:
npm i -S semantic-ui-css semantic-ui-react redux react-redux
Now let's import the semantic-ui css files in our application. Open the file index.js and change it to the following:
Now there's just some cleanup to do. Delete the following files:
> src/logo.svg
> src/App.css
And change src/App.js to remove the deleted file references, and add some flavour to it:
Alright, now we're ready to start configuring Redux.
Start up by creating an actions folder and adding the following files:
These will be our modal actions in these samples. As you can see they're pretty simple. When we call our openModal action creator, we expect to receive the modal props, for configuring its content, header, and such. Our closeModalaction currently doesn't receive any parameters, as it just states our intentions of closing the modal.
Now let's create our reducers. In this sample, we'll have a root reducer and a modal reducer. Their implementation is pretty simple, as you can see:
The rootReducer will just aggregate all of our existing reducers (just one in this sample), and the modalReducer will be responsible for defining the state of our modals. When we call the MODAL_OPEN action, we'll just pass along our received payload (remember the argument from our action creator?) to the store, and when we call the MODAL_CLOSE action, we'll clear the state, so we don't have any modal configuration.
Our store doesn't have anything special. It's just a call to Redux's createStorepassing along our rootReducer as you can see below:
With all of our configuration in place, it's time to configure our application to work with Redux. Open the index.js file and add the Provider component, as shown below:
Step 3: Creating our ModalManager component
Alright, enough with the boilerplate. Let's start writing our modal manager component!
First of all, let's add a button to our App component, so we can open our call our openModal action creator:
We just added a Button component, and configured it to call our openModalaction creator. In order to do that, we had to call the connect function from Redux. This function is responsible for connecting our component to the redux store, so we can dispatch actions without having to explicitly call the dispatch method in our components.
Now, let's create the main component. Start out by creating thecomponentsfolder and adding a ModalManager file with the following content:
This component is actually quite simple. It just gets the modals store from Redux, maps it to the modalConfiguration prop and, if that object is defined (meaning the OPEN_MODAL action was dispatched), renders a Modalcomponent (with some default configuration) inside itself.
When the CLOSE_MODAL action is dispatched, our modalConfiguration object is null, meaning our Modal component won't be rendered.
And that's it! Now we can have our components showing a semantic-ui modal without making them coupled to their component, and without having to manage it's visibility/state, and we also get the benefit of being able to use Redux's time travel debugging with our modals.
This is just a rough implementation, but it can help guide your next integrations with Redux. I hope you liked the post, and if you have any doubts, please leave a comment below and I will try to do my best to help :)