Luke F
Luke F

Reputation: 45

React-js: Objects are not valid as a React child

I'm not amazing at React but I've researched for hours with no hope so if anybody knows the issue here I would appreciate knowing why this is wrong and how to avoid this problem in the future.

Error: Objects are not valid as a React child (found: object with keys {}). If you meant to render a collection of children, use an array instead.

import { Avatar, IconButton } from "@material-ui/core";
import React, { useEffect, useState } from "react";
import "./Sidebar.css";
import SidebarChat from "./SidebarChat";
import SearchIcon from "@material-ui/icons/Search";
import RateReviewOutlinedIcon from "@material-ui/icons/RateReviewOutlined";
import { useSelector } from "react-redux";
import { selectUser } from "./features/userSlice";
import db, { auth } from "./firebase";

function Sidebar() {
  const user = useSelector(selectUser);
  const [chats, setChats] = useState([]);

  useEffect(() => {
    db.collection("chats").onSnapshot((snapshot) =>
      setChats(
        snapshot.docs.map((doc) => ({
          id: doc.id,
          data: doc.data(),
        }))
      )
    );
  }, []);

  const addChat = () => {
    const chatName = prompt("Please enter a chat name");
    if (chatName) {
      db.collection("chats").add({
        chatName: chatName,
      });
    }
  };

  return (
    <div className="sidebar">
      <div className="sidebar__header">
        <Avatar
          onClick={() => auth.signOut()}
          src={user.photo}
          className="sidebar__avatar"
        />
        <div className="sidebar__input">
          <SearchIcon />
          <input placeholder="Search" />
        </div>
        <IconButton varient="outlined" className="sidebar__inputButton">
          <RateReviewOutlinedIcon onClick={addChat} />
        </IconButton>
      </div>
      <div className="sidebar__chats">
        {chats.map(({ id, data: { chatName } }) => (
          <SidebarChat key={id} id={id} chatName={chatName} />
        ))}
      </div>
    </div>
  );
}

enter image description here

Upvotes: 2

Views: 2132

Answers (2)

Rakesh Pai R
Rakesh Pai R

Reputation: 66

Most probably, you are returning an object to display in Sidebar chat. If it has a value that is of type object, HTML won't be able to display an object as it is. It has to be some kind of primitive type such as integer, string etc. or it has to be an array of primitive types. In this case, probably in the SidebarChat component, you might be returning or displaying chat using the id passed from the Sidebar component.

You can display it by using the keys of that object.

let chats = [
{
   id: 1,
   data: "Hello"
},
{
   id: 2,
   data: "World"
}
];

This first chat can be displayed as:

let chatString = `No. of chats is: ${chats.length}. And the first chat is: ${chat[0].data}`;

This will give output as:

No. of chats is: 2. And the first chat is: Hello

Upvotes: 2

Delice
Delice

Reputation: 856

Don't return the mapping of chats without some conditional check to see if its populated or not.

Do this instead:

<div className="sidebar__chats">
        {chats && chats.map(({ id, data: { chatName } }) => (
          <SidebarChat key={id} id={id} chatName={chatName} />
        ))}
</div>

Upvotes: 1

Related Questions