简体   繁体   中英

How can I make it so that the same user cannot like a photo twice despite refreshing browser?

I'm trying to figure out how I could simulate the same like system that exists on IG. For example: If the current logged in user likes a photo and then tries to like again, then it should dislike - and vice versa. It doesn't matter if the user refreshes the page, logs out or clears browser cache since the liked data is coming from the server.

The useEffect() 's response that's being grabbed from the server looks like this:

{
  "url": "someUrl.com",
  "likes": 161,
  "UserID": "u-79696bbe-18e5-4e73-bfb7-e8c80b89e0a6",
  "name": "Paul",
  "photo_id": "p-a2bbb777-67de-4196-a92f-1effba006d13",
  "is_liked": 1,
  "user_id": "u-e6216642-5a01-4e69-913c-b2d19ef9b22e"
}
  • is_liked is 0 if the photo is disliked, 1 if it's liked
  • UserID is the user's id of the photo that's been liked
  • user_id is any logged in user that liked the photo (I know it's confusing but I'll change the name later)
  • photo_id is id of the photo that's been liked

The handleLike() 's response that's being grabbed from the server looks like this. It increments the total number of likes of the photo ( userLikes ) and toggles is_liked to 1

{
  "UserID": "u-79696bbe-18e5-4e73-bfb7-e8c80b89e0a6",
  "loggedInUserId": "u-43eaf8a2-2f47-4112-88f1-e08a382df59d",
  "likedPhotoId": "p-a2bbb777-67de-4196-a92f-1effba006d13",
  "userLikes": 163,
  "is_liked": 1
}

handleDislike() 's the opposite:

{
    "UserID": "u-79696bbe-18e5-4e73-bfb7-e8c80b89e0a6",
    "loggedInUserId": "u-43eaf8a2-2f47-4112-88f1-e08a382df59d",
    "dislikedPhotoId": "p-a2bbb777-67de-4196-a92f-1effba006d13",
    "userLikes": 162,
    "is_liked": 0
}

In conclusion, how can I make it so that the like system is identical to Instagram's? The endpoints are returning the correct data but implementing on the frontend is where I'm totally stuck

Here's the code:

const Grid = () => {
    let authToken                                                 = localStorage.getItem('token');

    const [gridData, setGridData]                                 = useState([]);
    const [userLikedPhotos, setUserLikedPhotos]                   = useState({});

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

        axios.get('http://127.0.0.1:8000/api/get-user-uploads-data', {headers})
            .then(resp => {
                console.log(resp.data);
                setGridData(resp.data);
            }).catch(err => {
            console.log(err);
        });

    }, []);

    const handleLikesBasedOnUserId = (likedPhotoUserId, userName, likedPhotoId, is_liked, user_id) => {
        if(userLikedPhotos[likedPhotoUserId]) {
            // dislike
            delete userLikedPhotos[likedPhotoUserId];
            gridData.find(photo => photo.UserID === likedPhotoUserId && photo.UserID !== user_id).likes--;
            handleDislike(likedPhotoUserId, userName, likedPhotoId);
        } else {
            // like
            userLikedPhotos[likedPhotoUserId] = true;
            gridData.find(photo => photo.UserID === likedPhotoUserId && photo.UserID !== user_id).likes++;
            handleLike(likedPhotoUserId, userName, likedPhotoId);
        }

        setUserLikedPhotos({...userLikedPhotos});
    };

    const handleLike = (likedPhotoUserId, userName, likedPhotoId) => {
        const url = 'http://127.0.0.1:8000/api/like';

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

        let data = {
            'UserID': likedPhotoUserId,
            'userName' : userName,
            'likedPhotoId' : likedPhotoId
        };

        axios.post(url, data, {headers})
            .then(resp => {
                console.log(resp.data);
            }).catch(err => {
            console.log(err);
        });

    };

    const handleDislike = (likedPhotoUserId, userName, likedPhotoId) => {
        const url = 'http://127.0.0.1:8000/api/dislike';

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

        let data = {
            'UserID': likedPhotoUserId,
            'userName' : userName,
            'dislikedPhotoId' : likedPhotoId
        };

        axios.post(url, data, {headers})
            .then(resp => {
                console.log(resp.data);
            }).catch(err => {
            console.log(err);
        });

    };

    return (
        <>
            <section className="gallery">
                <div className="container">
                    <div className="img-container">
                        {
                            gridData.map((photos, index) => {
                                return (
                                    <>
                                        <div className="userDetails">
                                            <span className="likesAmt">❤️ {photos.likes}</span>
                                            <Button variant="success" onClick={() => handleLikesBasedOnUserId(photos.UserID, photos.name, photos.photo_id, photos.is_liked, photos.user_id)}>Like</Button>
                                        </div>
                                    </>
                                )
                            })
                        }
                    </div>
                </div>
            </section>
        </>
    )
}

export default Grid;

I think you should set userLikedPhotos state with some of the value values grabbed from server in you useEffect and condition your buttons like this:

(userLikedPhotos?["is_liked"] ?
<Button>Dislike</Button>:
<Button>Like</Button>)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM