mongodb 如何在react用户界面中即时显示喜欢和不喜欢的数量

mwg9r5ms  于 2023-01-08  发布在  Go
关注(0)|答案(1)|浏览(100)

因此,我正在尝试实现喜欢和不喜欢的功能,每当有人点击喜欢按钮时,喜欢的数组就会更新,但如果在此之前没有刷新,数组的计数就会显示在用户界面中

import React, { useEffect, useState } from "react";
import axios from "axios";
import * as timeago from "timeago.js";
import { Link } from "react-router-dom";

import MoreVertRoundedIcon from "@mui/icons-material/MoreVertRounded";
import ThumbUpOutlinedIcon from "@mui/icons-material/ThumbUpOutlined";
import ThumbUpAltRoundedIcon from "@mui/icons-material/ThumbUpAltRounded";
import ThumbDownOffAltRoundedIcon from "@mui/icons-material/ThumbDownOffAltRounded";
import ThumbDownAltRoundedIcon from "@mui/icons-material/ThumbDownAltRounded";
import CommentRoundedIcon from "@mui/icons-material/CommentRounded";
import { useContext } from "react";
import { AuthContext } from "../../context/AuthContext";

const Post = ({ post }) => {
  const [user, setUser] = useState({});

  const { user: currentUser } = useContext(AuthContext);

  const likePost = async () => {
    try {
      await axios.put(`/post/${post?._id}/like`, { userId: currentUser._id });
    } catch (error) {}
  };
  const dislikePost = async () => {
    try {
      await axios.put(`/post/${post?._id}/dislike`, {
        userId: currentUser._id,
      });
    } catch (error) {}
  };

  useEffect(() => {
    const fetchUser = async () => {
      const response = await axios.get(`/users?userId=${post.userId}`);
      setUser(response.data);
    };
    fetchUser();
  }, [post.userId]);

  return (
    <div className="post">
      <div className="post-top">
        <div className="user">
          <Link
            to={`/profile/${user?.username}`}
            style={{ color: "inherit", textDecoration: "none" }}
          >
            <img
              src={
                user?.profilePicture
                  ? user?.profilePicture
                  : "https://thumbs.dreamstime.com/b/no-user-profile-picture-24185395.jpg"
              }
              alt=""
            />
          </Link>
          <div className="user-info">
            <Link
              to={`/profile/${user?.username}`}
              style={{ color: "inherit", textDecoration: "none" }}
            >
              <span className="username">{user?.username}</span>
            </Link>
            <span>{timeago.format(post.createdAt)}</span>
          </div>
        </div>
        <div>
          <MoreVertRoundedIcon style={{ cursor: "pointer" }} />
        </div>
      </div>
      {post?.image ? <hr /> : <hr style={{ display: "none" }} />}
      <div className="post-center">
        {post?.image ? (
          <img src={post?.image} alt="" />
        ) : (
          <img style={{ display: "none" }} />
        )}
      </div>
      <div className="post-desc">
        <div className="description">
          <span>{user?.username}</span>
          <span>{post?.description}</span>
        </div>
      </div>
      <div className="post-bottom">
        <div className="icons" onClick={likePost}>
          {post?.likes.includes(currentUser?._id) ? <ThumbUpAltRoundedIcon /> : <ThumbUpOutlinedIcon /> }
          <span>{post?.likes.length}</span>
        </div>
        <div className="icons" onClick={dislikePost}>
          {post?.likes.includes(currentUser?._id) ? <ThumbDownAltRoundedIcon /> : <ThumbDownOffAltRoundedIcon />}
          <span>{post?.dislikes.length}</span>
        </div>
        <div className="icons">
          <CommentRoundedIcon />
          <span>10</span>
        </div>
      </div>
    </div>
  );
};

export default Post;

我尝试使用使用效果,但我认为我在使用效果中做错了什么,我只使用了react context API不是redux

wztqucjr

wztqucjr1#

有两种解决方案:
1-如果您的put端点在喜欢或不喜欢某个帖子后返回了完整的帖子信息,您需要创建新的状态来保存您的帖子信息,如下所示,并相应地更新它:

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import * as timeago from 'timeago.js';
import { Link } from 'react-router-dom';

import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded';
import ThumbUpOutlinedIcon from '@mui/icons-material/ThumbUpOutlined';
import ThumbUpAltRoundedIcon from '@mui/icons-material/ThumbUpAltRounded';
import ThumbDownOffAltRoundedIcon from '@mui/icons-material/ThumbDownOffAltRounded';
import ThumbDownAltRoundedIcon from '@mui/icons-material/ThumbDownAltRounded';
import CommentRoundedIcon from '@mui/icons-material/CommentRounded';
import { useContext } from 'react';
import { AuthContext } from '../../context/AuthContext';

const Post = ({ post }) => {
  const [user, setUser] = useState({}),
    [currentPost, setCurrentPost] = useState(post);

  const { user: currentUser } = useContext(AuthContext);

  const likePost = async () => {
    try {
      const res = await axios.put(`/post/${currentPost?._id}/like`, { userId: currentUser._id });
      setCurrentPost(res.data);
    } catch (error) {
      console.log(error);
    }
  };
  const dislikePost = async () => {
    try {
      const res = await axios.put(`/post/${currentPost?._id}/dislike`, {
        userId: currentUser._id,
      });
      setCurrentPost(res.data);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    const fetchUser = async () => {
      const response = await axios.get(`/users?userId=${currentPost.userId}`);
      setUser(response.data);
    };
    fetchUser();
  }, [currentPost.userId]);

  return (
    <div className="post">
      <div className="post-top">
        <div className="user">
          <Link
            to={`/profile/${user?.username}`}
            style={{ color: 'inherit', textDecoration: 'none' }}
          >
            <img
              src={
                user?.profilePicture
                  ? user?.profilePicture
                  : 'https://thumbs.dreamstime.com/b/no-user-profile-picture-24185395.jpg'
              }
              alt=""
            />
          </Link>
          <div className="user-info">
            <Link
              to={`/profile/${user?.username}`}
              style={{ color: 'inherit', textDecoration: 'none' }}
            >
              <span className="username">{user?.username}</span>
            </Link>
            <span>{timeago.format(currentPost.createdAt)}</span>
          </div>
        </div>
        <div>
          <MoreVertRoundedIcon style={{ cursor: 'pointer' }} />
        </div>
      </div>
      {currentPost?.image ? <hr /> : <hr style={{ display: 'none' }} />}
      <div className="post-center">
        {currentPost?.image ? (
          <img src={currentPost?.image} alt="" />
        ) : (
          <img style={{ display: 'none' }} />
        )}
      </div>
      <div className="post-desc">
        <div className="description">
          <span>{user?.username}</span>
          <span>{currentPost?.description}</span>
        </div>
      </div>
      <div className="post-bottom">
        <div className="icons" onClick={likePost}>
          {currentPost?.likes.includes(currentUser?._id) ? (
            <ThumbUpAltRoundedIcon />
          ) : (
            <ThumbUpOutlinedIcon />
          )}
          <span>{currentPost?.likes.length}</span>
        </div>
        <div className="icons" onClick={dislikePost}>
          {currentPost?.likes.includes(currentUser?._id) ? (
            <ThumbDownAltRoundedIcon />
          ) : (
            <ThumbDownOffAltRoundedIcon />
          )}
          <span>{currentPost?.dislikes.length}</span>
        </div>
        <div className="icons">
          <CommentRoundedIcon />
          <span>10</span>
        </div>
      </div>
    </div>
  );
};

export default Post;

2-如果您有一个端点可以获取所需的发布信息,则可以按如下所示更新代码:

import React, { useEffect, useState } from 'react';
import axios from 'axios';
import * as timeago from 'timeago.js';
import { Link } from 'react-router-dom';

import MoreVertRoundedIcon from '@mui/icons-material/MoreVertRounded';
import ThumbUpOutlinedIcon from '@mui/icons-material/ThumbUpOutlined';
import ThumbUpAltRoundedIcon from '@mui/icons-material/ThumbUpAltRounded';
import ThumbDownOffAltRoundedIcon from '@mui/icons-material/ThumbDownOffAltRounded';
import ThumbDownAltRoundedIcon from '@mui/icons-material/ThumbDownAltRounded';
import CommentRoundedIcon from '@mui/icons-material/CommentRounded';
import { useContext } from 'react';
import { AuthContext } from '../../context/AuthContext';

const Post = ({ post }) => {
  const [user, setUser] = useState({}),
    [currentPost, setCurrentPost] = useState(post);

  const { user: currentUser } = useContext(AuthContext);

  const updatePostData = async () => {
    try {
      const res = await axios.get(`/post/${currentPost?._id}`, { userId: currentUser._id });
      setCurrentPost(res.data);
    } catch (error) {
      console.log(error);
    }
  };

  const likePost = async () => {
    try {
      await axios.put(`/post/${currentPost?._id}/like`, { userId: currentUser._id });
      await updatePostData();
    } catch (error) {
      console.log(error);
    }
  };
  const dislikePost = async () => {
    try {
      await axios.put(`/post/${currentPost?._id}/dislike`, {
        userId: currentUser._id,
      });
      await updatePostData();
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    const fetchUser = async () => {
      const response = await axios.get(`/users?userId=${currentPost.userId}`);
      setUser(response.data);
    };
    fetchUser();
  }, [currentPost.userId]);

  return (
    <div className="post">
      <div className="post-top">
        <div className="user">
          <Link
            to={`/profile/${user?.username}`}
            style={{ color: 'inherit', textDecoration: 'none' }}
          >
            <img
              src={
                user?.profilePicture
                  ? user?.profilePicture
                  : 'https://thumbs.dreamstime.com/b/no-user-profile-picture-24185395.jpg'
              }
              alt=""
            />
          </Link>
          <div className="user-info">
            <Link
              to={`/profile/${user?.username}`}
              style={{ color: 'inherit', textDecoration: 'none' }}
            >
              <span className="username">{user?.username}</span>
            </Link>
            <span>{timeago.format(currentPost.createdAt)}</span>
          </div>
        </div>
        <div>
          <MoreVertRoundedIcon style={{ cursor: 'pointer' }} />
        </div>
      </div>
      {currentPost?.image ? <hr /> : <hr style={{ display: 'none' }} />}
      <div className="post-center">
        {currentPost?.image ? (
          <img src={currentPost?.image} alt="" />
        ) : (
          <img style={{ display: 'none' }} />
        )}
      </div>
      <div className="post-desc">
        <div className="description">
          <span>{user?.username}</span>
          <span>{currentPost?.description}</span>
        </div>
      </div>
      <div className="post-bottom">
        <div className="icons" onClick={likePost}>
          {currentPost?.likes.includes(currentUser?._id) ? (
            <ThumbUpAltRoundedIcon />
          ) : (
            <ThumbUpOutlinedIcon />
          )}
          <span>{currentPost?.likes.length}</span>
        </div>
        <div className="icons" onClick={dislikePost}>
          {currentPost?.likes.includes(currentUser?._id) ? (
            <ThumbDownAltRoundedIcon />
          ) : (
            <ThumbDownOffAltRoundedIcon />
          )}
          <span>{currentPost?.dislikes.length}</span>
        </div>
        <div className="icons">
          <CommentRoundedIcon />
          <span>10</span>
        </div>
      </div>
    </div>
  );
};

export default Post;

相关问题