Create a Chat App with React and Nexmo

Published August 30, 2019 by Garann Means
Categories:

One of the simplest ways to communicate online is also among the simplest to add to your website, using React and Nexmo’s client-side JavaScript tooling. A chat application can provide customer service, facilitate collaboration on a project, or let you catch up with friends. And good news: if you’ve followed our previous full-stack React and Express tutorial, you already have most of the pieces you need to build one.

Prerequisites

To keep things short, let’s assume you have followed the React and Express tutorial. To start, you’ll again need a Nexmo Developer account and Node installed in your development environment. As in the full-stack example code, the example code for this tutorial will satisfy the latter requirement by using Glitch.

If you use the Nexmo Application you created for your full-stack app, you can generate one or two Conversation IDs and copy those to a text file for use in the next step. If you prefer to create a new application for this project, you can create the conversations from the command line.

Adding Chat Rooms to NexmoApp

To keep functionality separate, add a new component to your React application at client/src/Chatroom.js. For now, you can leave it mostly empty:

You can also add its CSS file, and populate that with whatever styling you like at any stage.

If you open NexmoApp.js you’ll see a couple of references to the Conversation component. The Chatroom component will be used similarly, so you can just replace those with references to Chatroom. They should be in the imports and the render function.

Within render, change the Chatroom component tag just slightly so that instead of passing invites, you’re passing chats:

The other properties passed to Chatroom already exist as part of user authentication and logging in, but chats isn’t currently part of the state. For this simple app, hard-code the Conversations you created above into the component’s initial state. You can give them any names you like to differentiate them for end users:

Because this app won’t manage conversations or invitations, you can also delete the code in login to get Conversations. This leaves that function only logging in and storing a reference to the Nexmo application:

A Simple Chatroom

You can leave all the User component code alone. It will continue to do the same thing, creating a new user or offering a list of existing users. Once the user is logged in, they can continue on to chat.

The Chatroom component will contain two states: choosing a chat room and the chat room itself. Behind the scenes, a chat room is just a Nexmo Conversation, so some of this component code will look similar to what’s in the Conversation component. You can stub out the functions and conditionals needed for both states to get started:

Joining a Chat

Since the user has a finite set of predefined chat rooms to choose from a dropdown will allow them to easily select one. If you only had a single chat, you could do away with this interface entirely. To produce a dropdown for the two chat rooms hard-coded in NexmoApp, loop over the array to build a set of options, then add them as children of a select:

When the dropdown value changes, joinConversation gets triggered. The joinConversation handler will get the chosen conversation by its ID from the Nexmo app and then join it. It also stores a reference to it and assigns it another event handler for incoming messages:

The onMessage handler gets triggered whenever there’s a new text event in the active Conversation. It receives information about the Conversation Member who triggered the event, and the event object itself. For a simple chat you can discard most of that information and save only the ID, user display name, and message text. This information can be concatenated onto a list of messages stored in the state:

If you were designing even a simple chat like this for production use, you’d want to plan to move older messages into a different storage object after some time. With any significant amount of traffic, a single array to hold all messages will inevitably cause problems.

Sending Messages

Once the user is logged in and has joined a chat, they’ll want to send and receive messages. This means you want to render a UI with, at minimum, an area for viewing messages and an input field for text. The JSX for this fills out the other branch of the main conditional in render. It iterates over your array of messages and renders anything received since the user joined the chat. Below that, it provides a textarea and button that set newly inputted text and send it, respectively:

The events raised by the message input are handled in setInput and sendInput. setInput very simply stores the inputted text in the component state:

The button handler, sendInput, takes the text stored in the state and passes it to the Conversation using sendText. It then clears the text in the state and in the textarea preceding it:

Chat Away!

Though it’s missing error handling and pays no attention to performance, now you have a very basic chat application. Stripping away the features of a production app reveals how little you need to provide core chat functionality:

  1. A User logged in to a Nexmo Application
  2. A Conversation for the User to join
  3. An event handler for received messages
  4. The sendText function to enable chatting

Whether you want to create an old school chat room, a pop-up conversation to help confused customers, or anything else, you can build it starting with these elements. You don’t need to handle any sockets or polling. And with React, you don’t need to do anything to trigger DOM updates. Now you can turn your attention to your UI and the app’s robustness.

Leave a Reply

Your email address will not be published.