Newsfeed.js
import React, { useEffect, useState } from "react";
import { Box, Center, useColorMode } from "@chakra-ui/react";
import NewsFeedPost from "@/components/newsfeed/NewsFeedPost";
import { useDispatch, useSelector } from "react-redux";
import { getNewsFeedPost } from "../redux/asyncActions/postAction";
import PostCardSkeleton from "../components/skeleton/PostCardSkeleton";
import { axiosInstance } from "../axiosConfig";
import AddNewsFeed from "../components/newsfeed/AddNewsFeed";
import PostLayout from "../components/large/PostLayout";
import {
loadedMore,
setError,
setMeta,
setPostExtend,
} from "../redux/slices/postSlice";
import InfiniteScroll from "react-infinite-scroller";
import Loading from "../components/small/Loading";
import { commonSlidercss, darkSlidercss } from "../GlobalStyles";
import { setCurrentPage } from "../redux/slices/siteSlice";
import NoPostYet from "../components/small/NoPostYet";
import { useNavigate, useSearchParams } from "react-router-dom";
import { LIMIT } from "../constants/pagination";
import HelmetWrapper from "../components/small/HelmetWrapper";
const NewsFeed = (query) => {
const dispatch = useDispatch();
const postState = useSelector((state) => state.postReducer);
const newsFeeds = postState.newsFeedPosts;
const metaInfo = postState.postMeta;
const [endReached, setEndReached] = useState(false);
const { colorMode } = useColorMode();
let [searchParams] = useSearchParams();
const [categoryId, setCategoryId] = useState("");
const [streamId, setStreamId] = useState("");
const [tag, setTag] = useState("");
const [totalPosts, setTotalPosts] = useState(0);
const navigate = useNavigate();
useEffect(() => {
if (query) {
navigate(query);
}
}, []);
useEffect(() => {
getTotal();
}, []);
useEffect(() => {
const stream_id = searchParams.get("stream_id") || "";
const category_id = searchParams.get("category_id") || "";
const tag = searchParams.get("tag") || "";
const searchKeyword = searchParams.get("keyword") || "";
setCategoryId(category_id);
setStreamId(stream_id);
setTag(tag);
dispatch(getNewsFeedPost(searchKeyword, category_id, stream_id, tag));
dispatch(setCurrentPage("NewsFeed"));
return () => {
dispatch(setPostExtend(false));
dispatch(setError(null));
};
}, [searchParams]);
const getTotal = async () => {
try {
const res = await axiosInstance.get(`post`);
setTotalPosts(res?.data?.post?.total);
} catch (e) {
console.log("Something went wrong while fetching total posts", e);
}
};
const loadFunc = async () => {
if (metaInfo && metaInfo?.next_page_url) {
const res = await axiosInstance.get(
`post?category=${categoryId}&stream=${streamId}&tag=${tag}&page=${
metaInfo?.current_page + 1
}&limit=${LIMIT}&published=${true}`
);
dispatch(
setMeta({
current_page: res?.data?.post?.current_page,
next_page_url: res?.data?.post?.next_page_url,
})
);
dispatch(loadedMore(res?.data?.post?.data));
} else {
setEndReached(true);
}
};
// I see this console also getting printed when I add new comment in one of the post
console.log("hey this is newsfeed let'see if I render again");
return (
<>
<HelmetWrapper title="NewsFeed - Alumsity" />
<PostLayout>
<Box
style={{
overflowY: "auto",
height: "calc(100vh - 120px)",
}}
css={colorMode === "light" ? commonSlidercss : darkSlidercss}
pr={{ base: "6px", lg: "0.8rem" }}
pb={{ lg: "2vh" }}
overflowX="hidden"
>
<AddNewsFeed />
{postState.isLoading ? (
<>
<PostCardSkeleton />
<PostCardSkeleton />
</>
) : newsFeeds ? (
<InfiniteScroll
pageStart={0}
loadMore={loadFunc}
hasMore={true || false}
useWindow={false}
loader={
metaInfo &&
metaInfo?.next_page_url && (
<div className="loader" key={0}>
<Loading />
</div>
)
}
>
{newsFeeds?.length > 0 ? (
newsFeeds?.map((li) => <NewsFeedPost data={li} key={li?.id} />)
) : (
<NoPostYet type="newsfeed" totalPosts={totalPosts} />
)}
</InfiniteScroll>
) : (
<Center>No Post Found</Center>
)}
</Box>
</PostLayout>
</>
);
};
export default NewsFeed;
NewsFeedPost.jsx
const NewsFeedPost = ({ data }) => {
const [showComment, setShowComment] = useState(false);
const [comments, setComments] = useState([]);
const [commentsCount, setCommentsCount] = useState(0);
const [currentPage, setCurrentPage] = useState(1);
const [nextPage, setNextPage] = useState(null);
const boxShadow = useColorModeValue(
"0px 1px 3px rgba(16, 24, 40, 0.1), 0px 1px 2px rgba(16, 24, 40, 0.06)",
"none"
);
const borderColor = useColorModeValue("#EAECF0", "#424242");
const bg = useColorModeValue("white", COLORS.darkGray);
const dispatch = useDispatch();
useEffect(() => {
if (showComment && data?.id) {
getComments(data?.id);
}
}, [showComment, data?.id]);
const getComments = async (id, PAGE) => {
try {
const res = await axiosInstance.get(
`comment/post/${id}?limit=${5}&page=${PAGE}`
);
setComments((prev) => [...prev, ...res?.data?.comment?.data]);
setCurrentPage(res?.data?.comment?.current_page);
setNextPage(res?.data?.comment?.next_page_url);
setCommentsCount(res?.data?.comment?.total);
} catch (err) {
console.log("error is", err);
dispatch(addNotice("Something went wrong"));
}
};
const loadMoreComments = () => {
if (nextPage) {
getComments(data?.id, currentPage + 1);
}
};
const addNewComment = (newComment) => {
console.log("new comment is here", newComment);
};
console.log("the data coming is", data);
console.log("the comments are", comments);
return (
<Box >
<Flex>
<Link to={`/post-detail/${data?.id}`}>
<Text fontWeight="400" fontSize={["sm", "md"]}>
{data?.title}
</Text>
</Link>
<Menu>
<MenuButton>
<BsThreeDots color="#7B6CB4" />
</MenuButton>
<Portal>
<PostOptions data={data} />
</Portal>
</Menu>
</Flex>
<Flex direction="row" align="center" justify="space-between">
<Box>
<PostInfo data={data} />
</Box>
{data.tags && <PostTag tags={data?.tags} />}
</Flex>
<PostContent data={data} />
<Divider mt="1rem" mb="0.5rem" />
<Flex
direction="row"
justify={{ base: "start", sm: "space-between" }}
mt="1rem"
align="center"
gap={["6%", 0]}
>
<CommentBox
data={data}
postDetail={false}
addCommentNew={(newComment) => addNewComment(newComment)}
/>
<Box width={{ base: "45%", sm: "45%", lg: "40%" }}>
<Flex
direction="row"
justify="space-around"
position="relative"
gap={[3, 0]}
>
<PostLikeUnLike data={data} />
<DataIconCount
icon="AiFillMessage"
count={data?.comments_count}
onClick={() => {
setShowComment((prev) => !prev);
}}
/>
<SocialShares postId={data?.id} />
</Flex>
</Box>
</Flex>
{comments?.length > 0 &&
comments?.map((li) => (
<Box
zIndex="10"
key={li?.id}
display={showComment ? "block" : "none"}
>
<PostComment data={li} />
</Box>
))}
{nextPage && showComment && (
<Button
borderRadius="10px"
width="full"
mt="1.5rem"
fontSize="12px"
fontWeight="400"
onClick={() => loadMoreComments(data)}
>
View More Comments
</Button>
)}
</Box>
);
};
export default NewsFeedPost;
CommentBox.jsx
import { Box, Input } from "@chakra-ui/react";
import React from "react";
import { useState } from "react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { axiosInstance } from "../../axiosConfig";
import { addNewComment, setResponse } from "../../redux/slices/postSlice";
import { addNotice } from "../../redux/slices/userSlice";
import AddPicker from "../small/AddPicker";
const CommentBox = ({
data,
addCount,
postDetail = true,
addCommentNew = null,
}) => {
const [commentInput, setCommentInput] = useState("");
const dispatch = useDispatch();
const addMyComment = async (e, id) => {
e.preventDefault();
let data = {
post_id: id,
content: commentInput,
};
try {
const res = await axiosInstance.post(`comment`, data);
if (postDetail === true) {
dispatch(addNewComment(res?.data?.comment));
} else if (!postDetail) {
addCommentNew(res?.data?.comment);
}
dispatch(addNotice(res.data.message));
dispatch(setResponse(true));
addCount && addCount();
setCommentInput("");
} catch (e) {
console.log(e);
dispatch(addNotice("Something went wrong while adding comment"));
}
};
return (
<Box w={{ base: "49%", sm: "50%", md: "70%", lg: "70%" }}>
<form
onSubmit={(e) => addMyComment(e, data?.id)}
style={{ position: "relative" }}
>
<Input
value={commentInput}
onChange={(e) => setCommentInput(e.target.value)}
fontSize={["9px", "10px", "xs", "xs"]}
placeholder="Add Response..."
// zIndex={0}
/>
<AddPicker setInput={setCommentInput} />
</form>
</Box>
);
};
export default CommentBox;
我将所有来自api的postMap到NewsFeedPost
组件。因为我必须根据postid显示注解,所以我为该组件中的每个Mappost创建了comments
和showComment
状态。
每当我添加新的评论到一个职位,所有其他子得到重新呈现和console.log("the data coming is")
和一个以下得到打印的所有Map职位。例如,如果我添加新的评论的第一个职位,console.log应该只打印该组件,但它继续得到打印的所有其他Map职位,如果有4个职位,我得到控制台日志6次
我想知道获取newsfeed中每个帖子的评论的最佳方法是什么?虽然更改一个Map子级的状态不会影响其他子级,但是每个帖子的状态是绑定在一起的吗?还是将数组Map到组件会为每个帖子创建新的状态?
1条答案
按热度按时间egdjgwm81#
你能试试这个再测试一次吗?