반응형
PedroTech님의 풀스택 강의 12일 차를 참고했습니다.
📌 Likes 테이블 생성하기
// ./server/models/Likes.js
// Likes 테이블 생성합니다.
module.exports = (sequelize, DataTypes) => {
const Likes = sequelize.define("Likes");
return Likes;
};
// ./server/models/Post.js
module.exports = (sequelize, DataTypes) => {
const Posts = sequelize.define("Posts", {...
});
Posts.associate = (models) => {
Posts.hasMany(models.Comments, {...
});
// Post테이블의 id와 Likes 테이블을 1:N 관계로 생성합니다.
Posts.hasMany(models.Likes, {
onDelete: "cascade",
});
};
return Posts;
};
// ./server/models/Users.js
module.exports = (sequelize, DataTypes) => {
const Users = sequelize.define("Users", {...
});
// Users의 id와 Likes 테이블을 1:N 관계로 생성합니다.
Users.associate = (models) => {
Users.hasMany(models.Likes, {
onDelete: "cascade",
});
};
return Users;
};
Likes 테이블을 생성한 뒤, Posts 테이블의 id와 Users 테이블의 id를 1:N 관계로 연결해 줍니다.
테이블을 생성할 때는 서버 연결을 끊는 것이 좋습니다.
📌 Likes router 생성하기
// ./server/routes/Likes.js
router.post("/", validateTocken, async (req, res) => {
const { PostId } = req.body;
const UserId = req.user.id;
// PostId와 UserId가 동일한 데이터 1개만 가져옵니다.
const found = await Likes.findOne({
where: { PostId: PostId, UserId: UserId },
});
// 좋아요를 눌렀을 때 만약 정보가 없다면 새로 추가하고,
// 이미 정보가 있다면 해당 데이터를 삭제해줍니다.
if (!found) {
await Likes.create({ PostId: PostId, UserId: UserId });
res.json({ liked: true });
} else {
await Likes.destroy({
where: { PostId: PostId, UserId: UserId },
});
res.json({ liked: false });
}
});
module.exports = router;
// ./server/index.js
// http://localhost:1234/likes를 호출하면 Likes router가 작동되도록 합니다.
const likesRouter = require("./routes/Likes");
app.use("/likes", likesRouter);
변수 설명(Likes.js)
1. PostId: 좋아요를 누른 Post의 id값을 가지고 있습니다.
2. UserId: 좋아요를 누른 사용자의 id값을 가지고 있습니다.
3. found: Likes 테이블에서 조건에 맞는 데이터를 저장하고 있습니다.
조건문 설명(Likes.js)
1. if(!found): 좋아요를 누른 정보가 없다면 Likes 테이블에 데이터를 추가해 주고, liked를 true로 변경 후 결과로 반환합니다.
2. else: 이미 좋아요를 눌렀다면 Likes 테이블에서 해당 데이터를 삭제한 뒤, liked를 false로 변경 후 결과로 반환합니다.
📌 좋아요 버튼과 함수 생성하기
// ./client/src/pages/Post.js
const { Posts, Likes } = require("../models");
// Likes 데이터를 포함해서 Posts 테이블의 데이터를 가져오도록 합니다.
// 1:N 관계로 연결되어 있기 때문에 알맞게 데이터를 가져올 수 있습니다.
router.get("/", async (req, res) => {
const listOfPosts = await Posts.findAll({ include: [Likes] });
res.json(listOfPosts);
});
// ./client/src/pages/Home.js
import React from "react";
import axios from "axios";
import { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
function Home() {
const [listOfPosts, setListOfPosts] = useState([]);
let navigate = useNavigate();
useEffect(() => {...
}, []);
// 좋아요 버튼을 클릭했을 때 호출될 함수입니다.
const likeAPost = (postId) => {
axios
.post(
"http://localhost:3001/likes",
{ PostId: postId },
{ headers: { accessTocken: localStorage.getItem("accessTocken") } }
)
.then((response) => {
setListOfPosts(
listOfPosts.map((post) => {
if (post.id === postId) {
if (response.data.liked) {
return { ...post, Likes: [...post.Likes, 0] };
} else {
const likesArray = post.Likes;
likesArray.pop();
return { ...post, Likes: likesArray };
}
} else {
return post;
}
})
);
});
};
return (
<div>
{listOfPosts.map((value, key) => {
return (
<div className="posts" key={key}>
<div className="title">...
</div>
<div>...
</div>
<div className="footer">
{value.username}
{/*
좋아요 버튼을 생성합니다.
*/}
<div className="likeContainer">
<button
type="button"
className="likeBtn"
onClick={() => {
likeAPost(value.id);
}}
>
Like
</button>
<label>{value.Likes.length}</label>
</div>
</div>
</div>
);
})}
</div>
);
}
export default Home;
좋아요 함수 설명(Home.js)
1. axios.post("경로", {PostId:~}, {header: ~}): 지정된 경로로 PostId와 header 이 데이터들을 전달합니다.
2. setListOfPosts(~): 좋아요를 누른 결과를 바로 적용되도록 하기 위해 활용했습니다.
3. if (post.id === postId): listOfPosts에 있는 포스트의 id와 동일한지 확인하고 liked의 상태에 따라 LIkes에 적절한 값을 전달해 줍니다.
- if (response.data.liked): 처음 좋아요를 눌렀을 때 post.Likes에 원래 데이터(...post.Likes)와 0을 추가해서 좋아요가 1개 증가할 수 있도록 합니다.
- else: 이미 좋아요를 누른 상태라면 post.Likes의 데이터를 가져온 뒤 1개를 삭제해서 좋아요 수가 하나 줄어들 수 있도록 합니다.
4. else: 좋아요 버튼을 누르지 않은 다른 post이기 때문에 그대로 결과를 반환합니다.
📌 결과
📌 느낀 점
커뮤니티 페이지를 구현할 계획이었는데 좋아요 버튼은 따로 테이블을 생성하는 게 좋은지 고민이 많았는데 이런 식으로 하면 깔끔하게 관리할 수 있을 것 같아서 좋은 방법을 배운 것 같아 아주 기쁩니다!!
무료로 이렇게 필요한 기능들을 배울 수 있다는 것에 참 감사한 마음입니다. PedroTech님..! 감사합니다!
728x90
'MySQL' 카테고리의 다른 글
React, MySQL 14일차 (글 수정과 비밀번호 변경하기) (0) | 2023.11.05 |
---|---|
React, MySQL 13일차 (글 작성자 정보 보기) (2) | 2023.10.30 |
React, MySQL 11일차 (로그아웃과 댓글 삭제하기) (0) | 2023.10.28 |
React, MySQL 10일차 (댓글 작성자 화면에 표시하기) (0) | 2023.10.24 |
React, MySQL 풀스택 9일차 (로그인 암호화해서 세션에 저장하기) (2) | 2023.10.21 |