Home > Enterprise >  React useState object not letting me access it's properties
React useState object not letting me access it's properties

Time:09-02

I'm making a chat app and I'm trying to create dynamic chat pages based on room page names within firestore. My chat component updates the chatbox title depending on what it finds off of firestore. I have determined that the query I'm using does in fact pull the data correctly through console.log.

function Chat() {
  const { roomId } = useParams();

  const [roomDetails, setRoomDetails] = useState();

  useEffect(() => {
    const roomQuery = query(
      collection(db, "rooms"),
      where("name", "==", roomId)
    );
    if (roomId) {
      const unsubscribe = onSnapshot(roomQuery, (snapshot) => {
        setRoomDetails(snapshot.docs.map((doc) => ({ ...doc.data() })));
      });
      return () => {
        unsubscribe();
      };
    }
  }, [roomId]);

  console.log(roomDetails);

  return (
    <div className="chat">
      <div className="chat__header">
        <div className="chat__headerLeft">
          <h4 className="chat__channelName">
            <strong>#{roomDetails?.name}</strong>
            <StarBorderOutlinedIcon />
          </h4>
        </div>
        <div className="chat__headerRight">
          <p>
            <InfoOutlinedIcon /> Details
          </p>
        </div>
      </div>
    </div>
  );
}

What doesn't work is the bottom section

<h4 className="chat__channelName">
  <strong>#{roomDetails?.name}</strong>
  <StarBorderOutlinedIcon />
</h4>

Within my browser the chat title will be blank and I presume that it's because it isn't reading the data or the data isn't defined yet. Here is what the useState looks like in console.

console.log output

    [{…}]0: 
      {name: 'general'}
      length: 1
      [[Prototype]]: Array(0)

Here's what Firestore looks like Firestore data/schema

CodePudding user response:

This will turn your state roomDetails into an array:

setRoomDetails(snapshot.docs.map((doc) => ({ ...doc.data() }))); 

And array doesn't have property name in it, so roomDetails?.name returns undefined. You need to access like this:

<strong>#{roomDetails?[0].name}</strong>

This should give you the UI output.

CodePudding user response:

I found the solution I changed the way the Data was queried

useEffect(() => {
  const roomQuery = query(
    collection(db, "rooms"),
    where("name", "==", roomId)
  );
  if (roomId) {
    const unsubscribe = onSnapshot(roomQuery, (snapshot) => {
      setRoomDetails(snapshot.docs.at(0).data());
    });
    return () => {
      unsubscribe();
    };
  }
}, [roomId]);

The way the data is rendered is the same. Hope this helps some future people.

  • Related