In-App chat in react.js with ZEGOCLOUD
Tags: javascript, react, webdev, zegocloud
Published: 2022-12-20 07:24:44

Almost any developer create a **[Chat Application](https://docs.zegocloud.com/article/14662)** in their initial career as a showcase project. I also did when I start learning about MERN Stack & I build chat app in with 2 different tech, Firebase with React.js & Socket.io (Node.js) with React.js.

As we grow in over experience we learn that thing can be done more easily and quickly by taking some help from pre build libraries instead of creating it custom.

Here is another feature of **[ZEGOCLOUD](https://www.zegocloud.com/)** called In-App chatting which love it, it just take a small configuration and chunk of code and your life can be easy.

## What I build
I have build a basic one-to-one chatting app using **ZEGOCLOUD**

## Tech Stack
React.js (Frontend)

## Configuration
1. Go to **ZEGOCLOUD** and make a account 
2. Go to dashboard and create a APP

![step-](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/diypbxnba9ikzuklbkzx.png)
3. Select **In-app chatting** feature
4. Go to Service Management option from dashboard and select In-App chatting feature


![step-](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rjbfcfev1a71muf2gnbt.png)

5. Active it 

![step-](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kjtd6xm36tx82snvqzr8.png)

6. Copy and save **AppID** for later use
7. Create a React.JS app using **create-reat-app** or any React framework. 
8. Create a component for chatting/messaging


## Application work flow
1. install zego-zim-web package in React.js and define AppID which you copy earlier 

![step-](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d94wr5huxasxyg111iws.png)

```
import React, { useEffect, useState } from 'react';
import { ZIM } from 'zego-zim-web';

var appID = 1423906504;
ZIM.create({ appID });
var zim = ZIM.getInstance();

function Chatting(props) {

    const [toUserId, setToUserId] = useState('')
    const [token, setToken] = useState('')
    const [userId, setUserId] = useState('')
    const [userName, setUserName] = useState('')

return (
        <div className='p-5 flex flex-col'>

            <label className='p-2 font-bold'>Token</label>
            <input className='border p-2 m-2' value={token} onChange={(e) => setToken(e.target.value)} />

            <label className='p-2 font-bold'>Your name</label>
            <input className='border p-2 m-2' value={userName} onChange={(e) => setUserName(e.target.value)} />

            <label className='p-2 font-bold'>UserId</label>
            <input className='border p-2 m-2' value={userId} onChange={(e) => setUserId(e.target.value)} />

            <button className='border p-2 m-2' onClick={handleLogin}>Login</button>

            <label className='p-2 font-bold'>Other person User Id </label>
            <input className='border p-2 m-2' value={toUserId} onChange={(e) => setToUserId(e.target.value)} />

            <button className='border p-2 m-2' onClick={handleSendMessage}>Send Message</button>

        </div>
    );
}
```

I also define some other states for later use

2. Both user need to generate **token** from dashboard with unique **userID ** save the taken for later use in frontend (the token can be auto generate from backend, If you are using any backend service).

3. After input userID and Token click login button and it will create a room for user 


![step-](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0t0tr9mmu0js1ofgxm5.PNG)

4. Once the User enter in room User can send message and can receive message from other user.


5. There are some event listeners which will help to indicate constantly whether the connection is stable or not also the receive event listener will constantly listen if any new message emit from any other user or not.

```
  useEffect(() => {
        // Set up and listen for the callback for receiving error codes. 
        zim.on('error', function (zim, errorInfo) {
            console.log('error', errorInfo.code, errorInfo.message);
        });

        // Set up and listen for the callback for connection status changes.
        zim.on('connectionStateChanged', function (zim, { state, event, extendedData }) {
            console.log('connectionStateChanged', state, event, extendedData);
            // When SDK logout occurred due to a long-time network disconnection, you will need to log in again. 
            if (state === 0 && event === 3) {
                zim.login({ userName }, token)
            }
        });

        // Set up and listen for the callback for receiving one-to-one messages. 
        zim.on('receivePeerMessage', function (zim, { messageList, fromConversationID }) {
            console.log('receivePeerMessage', messageList, fromConversationID);
        });

        // Set up and listen for the callback for token expires.
        zim.on('tokenWillExpire', function (zim, { second }) {
            console.log('tokenWillExpire', second);
            // You can call the renewToken method to renew the token. 
            // To generate a new Token, refer to the Prerequisites.
            zim.renewToken(token)
                .then(function ({ token }) {
                    // Renewed successfully.
                })
                .catch(function (err) {
                    // Renew failed.
                })
        });
        
        zim.on('receivePeerMessage', function (zim, { messageList, fromConversationID }) {
            console.log('receivePeerMessage', messageList, fromConversationID);
        });
    }, [])

```

As I define some event listeners for some Realtime work, To get current connect state, To get runtime message emit/receive, TO get is token expire and to get error if any.
Here is final component for one-to-one chatting app

```
import React, { useEffect, useState } from 'react';
import { ZIM } from 'zego-zim-web';

var appID = 1423906504;
ZIM.create({ appID });
var zim = ZIM.getInstance();

function Chatting(props) {

    const [toUserId, setToUserId] = useState('')
    const [token, setToken] = useState('')
    const [userId, setUserId] = useState('')
    const [userName, setUserName] = useState('')


    useEffect(() => {
        // Set up and listen for the callback for receiving error codes. 
        zim.on('error', function (zim, errorInfo) {
            console.log('error', errorInfo.code, errorInfo.message);
        });

        // Set up and listen for the callback for connection status changes.
        zim.on('connectionStateChanged', function (zim, { state, event, extendedData }) {
            console.log('connectionStateChanged', state, event, extendedData);
            // When SDK logout occurred due to a long-time network disconnection, you will need to log in again. 
            if (state === 0 && event === 3) {
                zim.login({ userName }, token)
            }
        });

        // Set up and listen for the callback for receiving one-to-one messages. 
        zim.on('receivePeerMessage', function (zim, { messageList, fromConversationID }) {
            console.log('receivePeerMessage', messageList, fromConversationID);
        });

        // Set up and listen for the callback for token expires.
        zim.on('tokenWillExpire', function (zim, { second }) {
            console.log('tokenWillExpire', second);
            // You can call the renewToken method to renew the token. 
            // To generate a new Token, refer to the Prerequisites.
            zim.renewToken(token)
                .then(function ({ token }) {
                    // Renewed successfully.
                })
                .catch(function (err) {
                    // Renew failed.
                })
        });
        
        zim.on('receivePeerMessage', function (zim, { messageList, fromConversationID }) {
            console.log('receivePeerMessage', messageList, fromConversationID);
        });
    }, [])


    const handleLogin = () => {
        try {
            const newUserDetails = { userName, userID: userId }
            zim.login(newUserDetails, token)
                .then(function (res) {
                    console.log("res", res)
                })
                .catch(function (err) {
                    console.log("err", err)
                });
        } catch (error) {
            console.log("error", error)
        }
    }

    const handleSendMessage = () => {
        try {
            var toUserID = toUserId;
            var config = {
                priority: 1 // Set priority for the message. 1: Low (by default). 2: Medium. 3: High.
            };

            // Send one-to-one text messages. 
            var messageTextObj = { type: 1, message: `user to ${toUserID} ` };
            zim.sendMessage(messageTextObj, toUserID, 0, config)
                .then(function ({ message }) {
                    console.log("message", message)
                })
                .catch(function (err) {
                    console.log("err", err)
                });
        } catch (error) {
            console.log("error", error)
        }
    }

    return (
        <div className='p-5 flex flex-col'>

            <label className='p-2 font-bold'>Token</label>
            <input className='border p-2 m-2' value={token} onChange={(e) => setToken(e.target.value)} />

            <label className='p-2 font-bold'>Your name</label>
            <input className='border p-2 m-2' value={userName} onChange={(e) => setUserName(e.target.value)} />

            <label className='p-2 font-bold'>UserId</label>
            <input className='border p-2 m-2' value={userId} onChange={(e) => setUserId(e.target.value)} />

            <button className='border p-2 m-2' onClick={handleLogin}>Login</button>

            <label className='p-2 font-bold'>Other person User Id </label>
            <input className='border p-2 m-2' value={toUserId} onChange={(e) => setToUserId(e.target.value)} />

            <button className='border p-2 m-2' onClick={handleSendMessage}>Send Message</button>

        </div>
    );
}

export default Chatting;
```

You can also get sample code in web(JavaScript) from here [Sample code for In-App chatting](https://docs.zegocloud.com/article/13967)

Documentation here [In-App Chatting Documentation](https://docs.zegocloud.com/article/13935)

Checkout my YouTube Channel for more content [**_YarCoder_**](https://www.youtube.com/c/yarcoder)