I making a chat app in react. I’m finding trouble in the ChatWindow component that displays all the chats. These chats are called from a backend server. This component is somehow making infinite amount of requests to the backend server which is crashing it. I used the network tab in dev tools and it showed 117 reqs in less than 10 secs. I faced the same problem in Sidebar.jsx. See the image: Output of network tab in devtools
Here is Sidebar.jsx:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Menu, Drawer, Button } from 'react-daisyui';
const api = `http://localhost:8000`;
function Sidebar({ onRecipientChange }) {
const [menuItems, setMenuItems] = useState([])
const [nick, setNick] = useState('')
const handleFriendSelect = (nickname, email) => {
onRecipientChange(nickname, email)
}
const fetchFriends = (async () => {
if (!window.localStorage.getItem('e')) {
const response = await axios.get(`${api}/users/profile/friends?email=${window.localStorage.getItem('mail')}`);
const res = response.data.values;
const frnds = JSON.parse(res);
let items = [];
if (Array.isArray(frnds) && frnds.length > 0 && res !== '["Start"]') {
const requests = frnds.map(async (friend) => {
const r = await axios.get(`${api}/users/profile?email=${friend}`);
return r.data.values[0].nickname;
});
const nicknames = await Promise.all(requests);
items = nicknames.map((nickname, index) => (
<Menu.Item onClick={() => handleFriendSelect(nickname, frnds[index])} style={{ borderRadius: 3 }}>
{(nickname) ? nickname : "None"}
</Menu.Item>
));
} else {
items.push(
<Menu.Item key="None" style={{ borderRadius: 3 }}>
None
</Menu.Item>
);
}
setMenuItems(items);
}
})
useEffect(() => {
fetchFriends()
}, [menuItems])
useEffect(() => {
async function fetchNick() {
if (!window.localStorage.getItem('e')) {
const res = await axios.get(`${api}/users/profile?email=${window.localStorage.getItem('mail')}`)
setNick(res.data.values[0].nickname)
}
}
fetchNick()
}, []);
return (
<>
<div>
<Drawer open={true} side={
<>
<Menu className="bg-base-200 rounded-sm text-lg h-full" style={{ width: 250 }}>
<Menu.Title className='text-xl' style={{ color: 'gray' }}>
<span className='flex justify-between'>
{nick}
<Button
color='ghost' size='sm' className='btn-circle'
onClick={
async function logout() {
window.localStorage.removeItem('mail')
window.location = '/login'
}
}
>
</Button>
</span>
</Menu.Title>
<Menu.Item>
<Menu.Title className='text-lg'>Me</Menu.Title>
<Menu.Item style={{ borderRadius: 3 }}>
Profile
</Menu.Item>
<Menu.Item style={{ borderRadius: 3 }}>
Inbox
</Menu.Item>
<Menu.Item style={{ borderRadius: 3 }}>
Friends
</Menu.Item>
</Menu.Item>
<Menu.Item>
<Menu.Title className='text-lg'>Chats</Menu.Title>
{menuItems}
</Menu.Item>
</Menu>
</>
} />
</div>
</>
);
}
export default Sidebar
Here is ChatWindow.jsx:
import { useEffect, useState } from 'react';
import { Button, Navbar, Input, Join, ChatBubble } from 'react-daisyui';
import axios from 'axios'
const api = `http://localhost:8000`;
function ChatWindow({ recipientNickname, recipientEmail }) {
const client = window.localStorage.getItem('mail')
const [chats, setChats] = useState([])
async function fetchChats() {
try {
const response = await axios.get(`${api}/users/messages?client=${client}&recipient=${recipientEmail}`);
if (response.data) {
setChats(response.data);
} else {
setChats([]);
}
} catch (e) {
console.log(e);
}
}
useEffect(() => {
fetchChats()
}, [chats])
const chatBubbles = chats.map((message, index) => (
<ChatBubble key={index} end={message.client === client}>
<ChatBubble.Message>{message.message}</ChatBubble.Message>
</ChatBubble>
))
return (
<div style={{ margin: 250, marginTop: 0, zIndex: 1 }}>
<div>
<Navbar>
<Navbar.Center style={{ alignItems: 'center' }}>
<Button tag="a" color="ghost" className="normal-case text-xl">
{recipientNickname || "Chats"}
</Button>
</Navbar.Center>
</Navbar>
</div>
<div className='chats'>
{chatBubbles}
</div>
<div>
<div style={{ position: 'fixed', bottom: 5, left: 0, right: 0 }}>
<Join>
<Input style={{ width: 1000, marginLeft: 260 }} placeholder='Send a message' className='join-item' />
<Button className='join-item rounded-s' color='success'>
Send
</Button>
</Join>
</div>
</div>
</div>
)
}
export default ChatWindow