Reputation: 3589
I'm trying to show the 2 previous recent comments based on createdAt, by implementing this filterMethod
const filterComments = props.comments.slice(0, inc).sort((a, b) => {
const date1 = new Date(a.createdAt) as any;
const date2 = new Date(b.createdAt) as any;
return date1 - date2;
});
inc
is variable that increments if user selects showMore
which isn't anything special
const showMoreComments = () => {
return filterComments.map((comment, i) => (
<div key={i}>
<CommentListContainer comment={comment} openModal={openModal} handleCloseModal={handleCloseModal} isBold={isBold} handleClickOpen={handleClickOpen} {...props} />
</div>
));
};
The problem is if the comments has more than 2 comments, the filtering gets out of order, so by default if there just 2 comments filterComments shows the recent 2 comments which works as i expect, but if there are more than 2 comments and i click on show more comments, it stops filtering correctly.
I've tried this method arr.slice(Math.max(arr.length - 5, 1))
In a javascript array, how do I get the last 5 elements, excluding the first element?
but its not really the answer i was looking for, i think this could be a reducer issue, or something.
What could i be doing wrong
showMoreMethod
const showComments = (e) => {
e.preventDefault();
if (inc + 2 && inc <= the_comments) {
setShowMore(inc + 2);
setShowLessFlag(true);
} else {
setShowMore(the_comments);
}
};
CommentList.tsx
import React, { Fragment, useState } from "react";
import Grid from "@material-ui/core/Grid";
import OurSecondaryButton from "../../../common/OurSecondaryButton";
import CommentListContainer from "../commentListContainer/commentListContainer";
import storeHooks from "../../../common/storeHooks";
function CommentList(props: any) {
const [showMore, setShowMore] = useState<Number>(2);
const [openModal, setOpenModal] = useState(false);
const [showLessFlag, setShowLessFlag] = useState<Boolean>(false);
const the_comments = props.comments.length;
const inc = showMore as any;
const min = Math.min(2, the_comments - inc);
const showComments = (e) => {
e.preventDefault();
if (inc + 2 && inc <= the_comments) {
setShowMore(inc + 2);
setShowLessFlag(true);
} else {
setShowMore(the_comments);
}
};
const handleClickOpen = () => {
setOpenModal(true);
};
const handleCloseModal = () => {
setOpenModal(false);
};
const showLessComments = (e) => {
e.preventDefault();
setShowMore(2);
setShowLessFlag(false);
};
const isBold = (comment) => {
return comment.userId === props.userId ? 800 : 400;
};
const filterComments = props.comments.slice(0, inc).sort((a, b) => {
const date1 = new Date(a.createdAt) as any;
const date2 = new Date(b.createdAt) as any;
return date1 - date2;
});
const showMoreComments = () => {
return filterComments.map((comment, i) => (
<div key={i}>
<CommentListContainer comment={comment} openModal={openModal} handleCloseModal={handleCloseModal} isBold={isBold} handleClickOpen={handleClickOpen} {...props} />
</div>
));
};
return (
<Grid>
<Fragment>
<div style={{ margin: "30px 0px" }}>
{props.comments.length > 2 ? (
<Fragment>
{min !== -1 ? (
<Fragment>
{min !== 0 ? (
<OurSecondaryButton onClick={(e) => showComments(e)} component="span" color="secondary">
View {min !== -1 ? min : 0} More Comments
</OurSecondaryButton>
) : (
<OurSecondaryButton onClick={(e) => showLessComments(e)} component="span" color="secondary">
Show Less Comments
</OurSecondaryButton>
)}
</Fragment>
) : (
<OurSecondaryButton onClick={(e) => showLessComments(e)} component="span" color="secondary">
Show Less Comments
</OurSecondaryButton>
)}
</Fragment>
) : null}
</div>
</Fragment>
{showLessFlag === true ? (
// will show most recent comments below
showMoreComments()
) : (
<Fragment>
{/* filter based on first comment */}
{filterComments.map((comment, i) => (
<div key={i}>
<CommentListContainer comment={comment} openModal={openModal} handleCloseModal={handleCloseModal} isBold={isBold} handleClickOpen={handleClickOpen} {...props} />
</div>
))}
</Fragment>
)}
</Grid>
);
}
// prevents un-necesary re renders
export default React.memo(CommentList);
reducer Reducer that handles the new state
case types.COMMENT_UPDATES_SUCCESS:
console.log(action);
const findCommentKey2 = state.posts.findIndex((x) => x.id === action.payload.comment.postId);
console.log(findCommentKey2);
draft.posts[findCommentKey2].Comments = [
action.payload.comment,
// add comment first, then sort it out by the most recent comment
...draft.posts[findCommentKey2].Comments,
];
return;
comment shape
[
{
"id": 177,
"comment_body": "",
"gifUrl": "https://media0.giphy.com/media/LRNxdA0soqs09YWa4F/giphy.gif?cid=e8452e68d3e94d3464efb70e1059fae80209a6b531b30b7d&rid=giphy.gif",
"userId": 9,
"postId": 15,
"createdAt": "2020-05-24T21:11:07.939Z",
"updatedAt": "2020-05-24T21:11:07.939Z",
"author": {
"username": "barnowl",
"gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
"bio": null
}
},
{
"id": 178,
"comment_body": "",
"gifUrl": "https://media2.giphy.com/media/xThtalTQnCNEatzgUU/giphy.gif?cid=e8452e68d3e94d3464efb70e1059fae80209a6b531b30b7d&rid=giphy.gif",
"userId": 9,
"postId": 15,
"createdAt": "2020-05-24T21:11:28.971Z",
"updatedAt": "2020-05-24T21:11:28.971Z",
"author": {
"username": "barnowl",
"gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
"bio": null
}
},
{
"id": 179,
"comment_body": "fsfsfssfsf",
"gifUrl": "",
"userId": 9,
"postId": 15,
"createdAt": "2020-05-24T21:12:31.920Z",
"updatedAt": "2020-05-24T21:12:31.920Z",
"author": {
"username": "barnowl",
"gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
"bio": null
}
},
{
"id": 175,
"comment_body": "fsfsfsfsfsf",
"gifUrl": "",
"userId": 9,
"postId": 15,
"createdAt": "2020-05-24T21:10:56.303Z",
"updatedAt": "2020-05-24T21:10:56.303Z",
"author": {
"username": "barnowl",
"gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
"bio": null
}
},
{
"id": 176,
"comment_body": "",
"gifUrl": "https://media3.giphy.com/media/Jrl4FlTaymFFbNiwU5/giphy.gif?cid=e8452e68f6a75bf1f94a134a15ab35ff1b0a09e2d060e1da&rid=giphy.gif",
"userId": 9,
"postId": 15,
"createdAt": "2020-05-24T21:11:01.152Z",
"updatedAt": "2020-05-24T21:11:01.152Z",
"author": {
"username": "barnowl",
"gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
"bio": null
}
},
{
"id": 180,
"comment_body": "fssfsffsf",
"gifUrl": "",
"userId": 9,
"postId": 15,
"createdAt": "2020-05-24T21:12:58.086Z",
"updatedAt": "2020-05-24T21:12:58.086Z",
"author": {
"username": "barnowl",
"gravatar": "https://api.adorable.io/avatars/400/bf1eed82fbe37add91cb4192e4d14de6.png",
"bio": null
}
}
]
Upvotes: 1
Views: 173
Reputation: 816
Shouldn't you sort them first before actually slicing them?
You can first use slice(0)
to clone the original array, as sort()
sorts the elements locally (and you shouldn't do that over the state).
This works for me:
const comments = [{createdAt: '2020-01-20'},{ createdAt: '2019-01-01'},{createdAt: '2019-05-01'},{createdAt: '2019-05-06'}];
const inc = 2;
const filterComments = comments.slice(0).sort((a, b) => {
const date1 = new Date(a.createdAt);
const date2 = new Date(b.createdAt);
return date2 - date1;
}).slice(0, inc);
console.log(filterComments);
Upvotes: 2