0

I am having a problem where I have an array of object that is passed down to a Child Component using Context, then I used the map() method to render out data of the objects inside of this array on the screen. I tried to implement an onClick event for each of the object that is rendered so that when I click on each individual element that is rendered out using the object, it will expand this element. Because if I don't do this then the onClick event will apply the click to all elements. So I am calling the expandEmail() function, and in this function I create a new array by [...inbox]. Note that inbox is the array of object that I passed down using context. Then I do newArray[index].showExpandEmail = !newArray[index].showExpandEmail. This works but for some reason I am also mutating the array inbox from context. I thought by using the spread operator, I am creating a new array. Please see the code below.

expandEmail(index, type) {
if (type === "Inbox") {
  const { context } = this.props;
  const { inbox } = context;
  console.log("expandEmail", inbox);
  // this.checkUnreadEmail(index);
  const newShowExpandEmail = [...inbox];
  console.log(newShowExpandEmail);
  newShowExpandEmail[index].showExpandEmail =
    !newShowExpandEmail[index].showExpandEmail;
  this.setState({
    composeEmail: false,
  });
} else if (type === "Sent Email") {
  const { context } = this.props;
  const { sentEmails } = context;
  const newShowExpandEmail = [...sentEmails];
  newShowExpandEmail[index].showExpandEmail =
    !newShowExpandEmail[index].showExpandEmail;
  this.setState({
    composeEmail: false,
  });
}

}

renderEmail(type) {
const { renderSubmittedTime } = Functions;
if (type === "Inbox") {
  // const { inbox } = this.state;
  const { context } = this.props;
  const { inbox } = context;
  console.log("inbox", inbox);
  return inbox.map((item, index) => {
    return (
      <li
        className="media ms-email clearfix"
        key={index}
        onClick={() => this.expandEmail(inbox, index, type)}
      >
        <div className="media-body ms-email-details">
          {" "}
          <span className="ms-email-sender">Customer: {item.name}</span>
          <span className="ms-email-email">
            Phone Number: {item.phone_number}
          </span>
          <span className="ms-email-email">Email: {item.email}</span>
          <h6 className="ms-email-subject">
            Event: {item.event_type}
          </h6>{" "}
          <span className="ms-email-unread">
            {item.read ? "Read" : "Unread"}
          </span>
          <span className="ms-email-time">
            Received at: {renderSubmittedTime(item)}
          </span>
          {!item.showExpandEmail && (
            <span className="ms-click-to-read">Click to read messages</span>
          )}
          <Collapse
            isOpened={item.showExpandEmail}
            className="ReactCollapse--collapse"
          >
            <p className="ms-email-msg">{item.message}</p>
            <div className="text-right">
              {" "}
              <button
                className="btn btn-primary mr-2"
                onClick={() =>
                  this.setState({ showModal: true, selectedItem: item })
                }
              >
                Reply
              </button>
            </div>
          </Collapse>
        </div>
      </li>
    );
  });
} else if (type === "Sent Email") {
  // const { sentEmails } = this.state;
  const { context } = this.props;
  const { sentEmails } = context;
  return sentEmails.map((item, index) => {
    return (
      <li
        className="media ms-email clearfix"
        key={index}
        onClick={() => this.expandEmail(index, type)}
      >
        <div className="media-body ms-email-details">
          {" "}
          <span className="ms-email-sender">To: {item.email}</span>
          <h6 className="ms-email-subject">Subject: {item.subject}</h6>{" "}
          <span className="ms-email-time">
            Sent at: {renderSubmittedTime(item)}
          </span>
          {!item.showExpandEmail && (
            <span className="ms-click-to-read">Click to read messages</span>
          )}
          <Collapse
            isOpened={item.showExpandEmail}
            className="ReactCollapse--collapse"
          >
            <p className="ms-email-msg">{item.message}</p>
          </Collapse>
        </div>
      </li>
    );
  });
}

}

Steve Ton
  • 36
  • 6
  • 1
    `[...inbox]` only creates a shallow copy of your array of objects. In the shallow copy the objects in your individual array entry still points to the same object in the original array. – Terry Sep 27 '22 at 17:19

0 Answers0