如何根据用户单击正确显示增量值?

发布于 2025-01-31 08:58:24 字数 3429 浏览 3 评论 0原文

我正在尝试复制用于学习目的的Instagram的喜欢系统。在下面的我的代码中,第一次单击任何照片的递增,这意味着正确显示了喜欢金额,以及指定的用户ID的DB列的正确递增/减少。

我面临的问题是:每当我尝试喜欢(单击)第一次照片之后的任何其他照片(如上所述正确更新)时,我需要几次单击它,而不是一次,为了使喜欢值要更改(增量/减少),即使到那时,它也被错误地显示和更新。

我该如何制作它,以便用户可以自由喜欢/不喜欢(单击一次并再次单击同一照片)任何订单的照片,以便更新正确的数据并在浏览器上显示?预先感谢您的任何反馈。

注意:我正在使用React查询来为每个用户获取数据库数据。

这是Gallery.js

const [currentUserClicks, setCurrentUserClicks]               = useState(1);

async function fetchUploads() {
    const headers = {
        "Accept": 'application/json',
        "Authorization": `Bearer ${authToken}`
    };

    const {data} = await axios.get('http://localhost/api/get-user-uploads-data', {headers});
    return data;
}

const handleLikesBasedOnUserId = (likedPhotoUserId) => {
    if(currentUserClicks > 1) {
        setCurrentUserClicks(currentUserClicks - 1);
        handleDisLike(likedPhotoUserId); // sends data to server to decrement DB column
    } else {
        setCurrentUserClicks(currentUserClicks + 1);
        handleLike(likedPhotoUserId); // sends data to server to increment DB column
    }
};

const handleLike = (likedPhotoUserId) => {
    const url = 'http://localhost/api/like';

    const headers = {
        "Accept": 'application/json',
        "Authorization": `Bearer ${authToken}`
    };

    let data = {
        'UserID': likedPhotoUserId,
        'likeCount': currentUserClicks
    };

    axios.post(url, data, {headers})
        .then(resp => {
            console.log("handleLike",resp.data.userLikes[0].likes);
        }).catch(err => {
        console.log(err);
    });

};

const handleDisLike = (likedPhotoUserId) => {
    const url = 'http://localhost/api/dislike';

    const headers = {
        "Accept": 'application/json',
        "Authorization": `Bearer ${authToken}`
    };

    let data = {
        'UserID': likedPhotoUserId,
        'likeCount': currentUserClicks
    };

    axios.post(url, data, {headers})
        .then(resp => {
            console.log("handleDisLike", resp.data.userLikes[0].likes);
        }).catch(err => {
        console.log(err);
    });

};

const { data } = useQuery('uploads', fetchUploads); 

return(
      <div className="main">
            <ul className="cards">
                {
                    data.map((photos, index) => {
                        return <Grid
                            src={photos.url}
                            likes={photos.likes}
                            currentUserClicks={currentUserClicks}
                            key={index}
                            onClick={handleLikesBasedOnUserId}
                            userId={photos.UserID}
                        />
                    })
                }
            </ul>
       </div>
 );

这里的Grid.js:

const Grid = (props) => {
     const [likes, setLikes] = useState(props.likes);

       return (
            <>
                <img src={props.src} alt="Photo" className="gallery-img" onClick={() => props.onClick(props.userId, props.currentUserClicks > 1 ? setLikes(props.likes) : setLikes(props.likes + 1))}/>
                <span style={{display: 'none'}}>{props.currentUserClicks}</span>
                <h5 className="likes">Likes: {likes}</h5>
          </>
    );
}

I'm trying to replicate the likes system that Instagram for learning purposes. With my code below, the very first click on any photo increments correctly which means the likes amount is correctly being displayed as well as the specified user ID's DB column is correctly being incremented/decremented.

The problem I'm facing is: Whenever I try to like (click) any other photo after the first photo click (which correctly updates as mentioned above), I'll need to click it a few times, instead of once, in order for the likes value to change (increment/decrement) and even then, it's being displayed and updated incorrectly.

How can I make it so that the user can freely like/dislike (click once and click again on the same photo) any photo in any order so that the correct data is updated and displayed on the browser? Thanks in advance for any feedback.

Note: I'm using React Query to fetch DB data for each user.

Here's Gallery.js

const [currentUserClicks, setCurrentUserClicks]               = useState(1);

async function fetchUploads() {
    const headers = {
        "Accept": 'application/json',
        "Authorization": `Bearer ${authToken}`
    };

    const {data} = await axios.get('http://localhost/api/get-user-uploads-data', {headers});
    return data;
}

const handleLikesBasedOnUserId = (likedPhotoUserId) => {
    if(currentUserClicks > 1) {
        setCurrentUserClicks(currentUserClicks - 1);
        handleDisLike(likedPhotoUserId); // sends data to server to decrement DB column
    } else {
        setCurrentUserClicks(currentUserClicks + 1);
        handleLike(likedPhotoUserId); // sends data to server to increment DB column
    }
};

const handleLike = (likedPhotoUserId) => {
    const url = 'http://localhost/api/like';

    const headers = {
        "Accept": 'application/json',
        "Authorization": `Bearer ${authToken}`
    };

    let data = {
        'UserID': likedPhotoUserId,
        'likeCount': currentUserClicks
    };

    axios.post(url, data, {headers})
        .then(resp => {
            console.log("handleLike",resp.data.userLikes[0].likes);
        }).catch(err => {
        console.log(err);
    });

};

const handleDisLike = (likedPhotoUserId) => {
    const url = 'http://localhost/api/dislike';

    const headers = {
        "Accept": 'application/json',
        "Authorization": `Bearer ${authToken}`
    };

    let data = {
        'UserID': likedPhotoUserId,
        'likeCount': currentUserClicks
    };

    axios.post(url, data, {headers})
        .then(resp => {
            console.log("handleDisLike", resp.data.userLikes[0].likes);
        }).catch(err => {
        console.log(err);
    });

};

const { data } = useQuery('uploads', fetchUploads); 

return(
      <div className="main">
            <ul className="cards">
                {
                    data.map((photos, index) => {
                        return <Grid
                            src={photos.url}
                            likes={photos.likes}
                            currentUserClicks={currentUserClicks}
                            key={index}
                            onClick={handleLikesBasedOnUserId}
                            userId={photos.UserID}
                        />
                    })
                }
            </ul>
       </div>
 );

Here's Grid.js:

const Grid = (props) => {
     const [likes, setLikes] = useState(props.likes);

       return (
            <>
                <img src={props.src} alt="Photo" className="gallery-img" onClick={() => props.onClick(props.userId, props.currentUserClicks > 1 ? setLikes(props.likes) : setLikes(props.likes + 1))}/>
                <span style={{display: 'none'}}>{props.currentUserClicks}</span>
                <h5 className="likes">Likes: {likes}</h5>
          </>
    );
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温柔一刀 2025-02-07 08:58:24

如果您使用的是React-Query,那么我看不出需要在本地状态中使用CurrentUserClicks。通常,它会像这样:

  • 您有一个查询,可以获取照片数据,包括喜欢。
  • 当用户单击“喜欢”按钮时,您可以进行突变在突变成功时更新后端的状态
  • ,您将查询无效,该查询将重新查询照片查询并因此显示正确的查询状态。

您可以使用乐观的更新通过QueryClient.SetQueryData更新React-Query Cache 。这样可以确保按钮立即对用户交互产生反应。

if you are using react-query, then I don't see the need of having currentUserClicks in local state. Usually, it would go like this:

  • You have a query that fetches photo data, including likes.
  • When the user clicks the like button, you make a mutation to update the state on the backend
  • When the mutation is successful, you invalidate the query, which will re-fetch the photo query and thus show the correct state.

You can make the whole process snappier by using optimistic updates, where you would locally update the react-query cache via queryClient.setQueryData before you fire off the mutation. That makes sure the like button instantly reacts to the user interaction.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文