Redux explained as a random messenger group conversation

reduxgroupchat
Image source: Pixabay

Like it or hate it, redux has become defacto state management system for complex reactjs and reactnative projects. However it does takes a little time to figure out the basic concepts and generate boilerplate code before one can use redux effectively in your next project and the official documentation seems a little daunting for people just starting their way into front end development. So I am writing this article to explain redux concepts by taking an analogy of a random group chat conversation as todo examples are old school and boring.

The three main components which make up redux are store,actions and reducers.Suppose you want to share some funny meme with your friends online. First thing you will need is a group containing all your friends to share your meme with them.In redux world this online group of your friends is called a store. It is a group to which all your friends(components) have subscribed to and it acts as a central repository to save all your group chat history. In redux world a store is an immutable entity which essentially means that a new copy of store is created on each update i.e. if someone posts some joke in your group all the subscribers(components) will receive a new copy of store with the new message appended at the end of chat history. The advantage is that you can see and control the state of store from initial state to final one or in our case simply view your entire chat history whenever you feel nostalgic or have nothing else to doΒ πŸ˜‰

For messages to pop up in group chat we first need to take the actionΒ of opening chat,typing the message and hit post button. Similarly in redux world, actions are the ones that invoke change in state of store.Once we hit the post button there has to be some built-in mechanism that takes your input from action, lookup current state of chat history and update the conversation for all subscribers based on your posting action. This built-in mechanism is the reducer in redux world which is a function that takes the action parameters and current state of store as input and returns new state of the store.

Enough with the boring theory stuff, lets us now build our own simple chat application to understand the concepts better. Here is a demo of what we are actually going to build today:

 

First create a new react project and install redux components along with react-bootstrap for creating a simple grid and chat-template to allow posting of messages:

The entire directory structure for the src folder of app is as follows:

.
β”œβ”€β”€ actions
β”‚Β Β  β”œβ”€β”€ actionTypes.js
β”‚Β Β  └── index.js
β”œβ”€β”€ App.css
β”œβ”€β”€ App.js
β”œβ”€β”€ App.test.js
β”œβ”€β”€ components
β”‚Β Β  β”œβ”€β”€ global
β”‚Β Β  β”‚Β Β  └── Navbar.js
β”‚Β Β  └── screens
β”‚Β Β  β”œβ”€β”€ ChatInput.js
β”‚Β Β  β”œβ”€β”€ css
β”‚Β Β  β”‚Β Β  └── ChatInput.css
β”‚Β Β  └── GroupChat.js
β”œβ”€β”€ index.css
β”œβ”€β”€ index.js
β”œβ”€β”€ logo.svg
└── reducers
β”œβ”€β”€ chatOperations.js
└── index.js

Here components folder contains all reusable components like navbar in global folder and specific page level components in screens folder,actions folder contains action specific file while reducer specific files are saved in reducers folder. Let us first build basic ui for our web app before we dive into redux…

First let us create simple Navbar component in global folder within components:

Next we create a simple ChatInput component to allow user to post messages in screens folder within components:

Now we need to display messages as chat conversation in GroupChat component within screens folder in components:

Next integrate all this components in App.js component:

Phew…now that we are done with initial ui setup let’s get our hands dirty in building redux components 😎 :

In our case I am going to define a single action which allows the user to post messages to store. First define action constant in actionTypes.js file within actions folder as follows:

Next we will define our reducer viz chatOperations.js file in reducers folder:

Whenever we will encounter post message action, we simply push a new message to state object and update state of store.

Next pass this reducer to combineReducers in index.js in reducers folder:

Now lets us define action functions which calls this post message reducers in index file in actions folder:

Next modify main index.js Β in src folder as follows:

We have set up a simple redux store, applied createlogger for getting log inputs and used redux persist to store object state in localStorage. You can uncomment line 14 and 18 to get them working. Next we have passed store state to App.js using provider.

Now modify App.js as follows:

Here App.js recieves store state as prop values using function mapStateToProps and available actions as props using mapDispatchToProps. I have used different syntax for both this functions and you can use any one which seems comfortable to you. Next we have passed the messageItems and actions props from app.js to ChatInput and GroupChat components on lines 23,24 and 28.

Next update onClick handler function of chatInput.js component(handlePostClick) as follows:

This line calls action to udpate state in redux store and our chatOperations reducer will get the message and profile pic url from the above action.

Now modify GroupChat.js file to listen for posted messages and update the messages states:

We have modified GroupChat to get populate messages from store before first render in constructor method and update messages queue when post messages action is dispatched in componentWillReceiveProps method.

You will have to import bootstrap css files in index.html along give some further styling to components and if you face any issues then you can check out the source code on my github repo for reference here.

Bonus Tips:

  • If you want to develop similar app in react native then you can use reactnative-gifted-chat module and follow similar flow.
  • I have not added a backend connection anywhere in the app since the emphasis was on learning redux but if required you can handle all ajax requests to backend in the reducer and update state of store accordingly.

Connect Deeper:

In the next article I will probably try to cover backend integration of the above chat app using Apollo graphql client and graphql server in nodejsΒ andΒ real-time face detection and recognition using opencv,nodejs and reactjs. If you are interested in getting notified about future posts then you can follow our facebook page here: Technoetics or subscribe to our mailing list below. I value your time as much as I value my own work so I won’t be spamming your inbox about useless offers ever and will email you only once in a month with relevant articles that will be personally hand-picked by me based on your interests πŸ˜€

Technoetics newsletter

Get notified about upcoming articles,tips and tricks personally hand-delivered to your inbox

 

 

Share post-
About Saurabh Mhatre 70 Articles
Currently working in web and hybrid application development