React Virtuoso: Making a list of custom items

1.1k Views Asked by At

I am trying to make a custom component that utilizes React Virtuoso to make a list that renders chat bubbles. I think I am missing some understanding, particularly how the prop itemContent works.

Based on the example given in the official documentation, itemContent prop takes in a function that is in the form "(index, item) => whatever I want to return" while the data prop takes in the actual list itself. I am very confused about the term "index" and what role it plays here, and what exactly the callback function that is passed to itemContent is doing. Any help is appreciated.

Here is the code:

const testList = () => {
  return (
    <List>
      <ChatBubble message="Message 1" type="sent" />
      <ChatBubble message="Message 2" type="sent" />
      <ChatBubble message="Message 3" type="received" />
      <ChatBubble message="Message 4" type="sent" />
      <ChatBubble message="Message 5" type="received" />
      <ChatBubble message="Message 6" type="received" />
      <ChatBubble message="Message 7" type="sent" />
    </List>
  );
};

export default function ChatWindow(props) {
  const [currentList, setCurrentList] = useState();

  useEffect(() => {
    setCurrentList(testList);
  }, [currentList]);

  return (
    <Virtuoso data={currentList} itemContent={(index, item) => item}></Virtuoso>
  );
}

And code for chat bubbles:

import React, { useState, useEffect } from "react";
import { Card, CardContent, Typography, Grid } from "@mui/material";

export default function ChatBubble(props) {
  const [type, setType] = useState(null);
  const [color, setColor] = useState(null);
  const [alignment, setAlignment] = useState(null);

  useEffect(() => {
    setType(props.type);
    if (type == "sent") {
      setAlignment("flex-end");
      setColor("primary");
    } else {
      // received
      setAlignment("flex-start");
      setColor("secondary");
    }
  });

  return (
    <Grid container item p={2} justifyContent={alignment}>
      <Card
        alignItems="center"
        justifyContent="center"
        variant="outlined"
        sx={{ bgcolor: color + ".main" }}
      >
        <CardContent>
          <Typography color={color + ".contrastText"}>
            {props.message}
          </Typography>
        </CardContent>
      </Card>
    </Grid>
  );
}
0

There are 0 best solutions below