the_namikaze
the_namikaze

Reputation: 69

React routes not rendering the specific component

I am trying to make a WhatsApp Web clone using React and Firebase. Here I want to implement the functionality where clicking on a specific chat in the sidebar on left of window opens a chat body on right. For this I am using Switch and Route in React. By default, I want to show the sidebar in all cases but display the Chat body only when the user clicks on one of the chats. For this the code in my App.js is :

import React from "react";
import Chat from "./Chat";
import { BrowserRouter,Switch, Route } from "react-router-dom";
import "./App.css";
import Sidebar from "./Sidebar";

function App() {
  return (
    <div className="app">
      <div className="app_body">
        <BrowserRouter>
          <Switch>
            <Sidebar />

            <Route exact path="/" component={Chat} />

            <Route path="/rooms/:roomId" component={Chat} />
            </Switch>
        </BrowserRouter>
      </div>
    </div>
  );
}

export default App;

However, only the sidebar gets displayed every time.The chat doesn't get displayed even when I have added the component Chat in my exact home route ("/") as shown here

When I interchange the Chat and Sidebar components in the code, only the Chat component gets displayed like this

What is wrong in this code? I tried to search for a lot of answers but couldn't find any answers to this. I tried switching routes, components and everything

The codes for my specific components are :

Chat :

import React, { useState, useEffect } from "react";
import "./Chat.css";
import { Avatar, IconButton } from "@material-ui/core";
import {
  Search,
  AttachFile,
  MoreVert,
  InsertEmoticon,
  Mic,
} from "@material-ui/icons";

import { useParams } from "react-router-dom";
import db from "./firebase";

function Chat() {
  const [input, setInput] = useState("");
  const { roomId } = useParams();
  const [roomName, setRoomName] = useState("");
  useEffect(() => {
    if (roomId) {
      db.collection("rooms")
        .doc(roomId)
        .onSnapshot((snapshot) => setRoomName(snapshot.data().name));
    }
  }, [roomId]);

  const sendMessage = (e) => {
    e.preventDefault();
    console.log(input);
    setInput("");
  };

  return (
    <div className="chat">
      <div className="chat_header">
        <Avatar src="https://res.cloudinary.com/shatadrucld/image/upload/v1597305602/qpqnqwyuokbupddqwuwc.jpg" />
        <div className="chat_headerInfo">
          <h3>{roomName}</h3>
          <p>Last seen at .....</p>
        </div>
        <div className="chat_headerRight">
          <IconButton>
            <Search />
          </IconButton>
          <IconButton>
            <AttachFile />
          </IconButton>
          <IconButton>
            <MoreVert />
          </IconButton>
        </div>
      </div>
      <div className="chat_body">
        <p className={`chat_message ${true && "chat-receiver"}`}>
          <span className="chat_name">Shatadru Roy</span>Hey guys
          <span className="chat_timestamp">3:52pm</span>
        </p>
      </div>
      <div className="chat_footer">
        <InsertEmoticon />
        <form>
          <input
            type="text"
            placeholder="Type a message"
            value={input}
            onChange={(e) => {
              setInput(e.target.value);
            }}
          ></input>
          <button type="submit" onClick={sendMessage}></button>
        </form>
        <Mic />
      </div>
    </div>
  );
}

export default Chat;

Sidebar :

import SidebarChat from "./SidebarChat";
import db from "./firebase";

function Sidebar() {
  const [rooms, setRooms] = useState([]);

  useEffect(() => {
    const unsubscribe=db.collection("rooms").onSnapshot((snapshot) => {
      setRooms(
        snapshot.docs.map((doc) => ({
          id: doc.id,
          data: doc.data(),
        }))
      );
    });
    return ()=>{
      unsubscribe();
    }
  }, []);

  return (
    <div className="sidebar">
      <div className="sidebar_header">
        <Avatar />
        <div className="sidebar_headerRight">
          <IconButton>
            <DonutLarge />
          </IconButton>
          <IconButton>
            <Chat />
          </IconButton>
          <IconButton>
            <MoreVert />
          </IconButton>
        </div>
      </div>

      <div className="sidebar_search">
        <div className="sidebar_searchContainer">
          <SearchOutlined />
          <input placeholder="Seacrh chats" type="text"></input>
        </div>
      </div>
      <div className="sidebar_chats">
        <SidebarChat addNewChat />
        {rooms.map(room=>{
          return (<SidebarChat key={room.id} id={room.id} name={room.data.name}  />)
        })}
      </div>
    </div>
  );
}

export default Sidebar;

Please help me with this problem. I am new to these concepts so I am completely stuck at this phase. I tried several solutions in the internet but none of them is working.

Edit : I also tried to use withRouter but it is not working either

Upvotes: 0

Views: 169

Answers (1)

wyfy
wyfy

Reputation: 361

Try moving <Sidebar /> out of the <Switch> component. If is persistent then it should be outside of <Switch/>

Upvotes: 1

Related Questions