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>
);
});
}
}