📁 북마크 기능 미리보기


북마크 기능 구현 과정을 간단하게 정리해보자면 다음과 같다.
프론트
- bookmark 버튼 및 bookmark 페이지 형성
백엔드
- bookmark 테이블 생성(tweets 테이블과 관계형성)
- getTweet API에 isBookmark 변수 생성후 트윗 북마크 유무 알려주기.
=>isBookmark변수는 false가 기본값. isBookmark가 true인 트위터 게시물은 bookmark 페이지에서 bookmarkAPI 호출시 해당 데이터 넘겨주기
실제 구현한 코드
sequelize에 bookmark 테이블 생성하고 tweet_id을 기준으로 tweet데이터가 담겨져 있는 tweets 테이블과 관계형성하였다.
➡️ 관계를 형성한 이유는 나중에 북마크 페이지에서 데이터를 가지고 올때 tweet_id를 기준으로 Tweets테이블과 join하여 북마크 트윗게시물 데이터를 가지고 올 수 있기때문이다.
bookmark.ts
@Table({
timestamps: false,
tableName: "bookmark",
charset: "utf8",
collate: "utf8_general_ci",
})
export class Bookmark extends Model {
@Column({
type: DataType.INTEGER,
autoIncrement: true,
primaryKey: true,
})
id!: IntegerDataType;
@Column({
type: DataType.STRING,
allowNull: true,
})
content!: string;
@ForeignKey(() => Tweets)
@Column({
type: DataType.INTEGER,
allowNull: false,
})
tweet_id!: IntegerDataType;
@Column({
type: DataType.INTEGER,
allowNull: true,
})
user_id!: IntegerDataType;
@BelongsTo(() => Tweets)
tweets!: Tweets;
}
saveBookmark.ts
router.post(
"/",
verifyAccessToken,
verifyRefreshToken,
async (req: any, res: Response, next: NextFunction) => {
await Bookmark.create({
tweet_id: req.body.tweet_id,
user_id: req.body.id,
}).then((result) => {
res.status(201).json(result);
});
}
);
router.post(
"/delete",
verifyAccessToken,
verifyRefreshToken,
async (req: any, res: Response, next: NextFunction) => {
await Bookmark.destroy({
where: {
tweet_id: req.body.tweet_id,
user_id: req.body.id,
},
}).then((result) => {
res.status(201).json(result);
});
}
);
제일 처음 페이지를 로딩했을때 모든 트윗 데이터를 가져오기 위해 사용하는 getTweet API 코드이다.
isBookmark라는 변수를 하나 만들어서 해당 트윗 북마크 유무를 알려준다.
현재 로그인한 유저 데이터(currentUser)를 조회한 후
=> 유저가 북마크를 누른 tweet데이터가 있는지 찾아보고
=> 북마크된 트윗의 경우 is_bookmark를 true값으로 넘겨준다.(기본값은 false)
router.get(
"/select",
verifyRefreshToken,
async (req: any, res: Response, next: NextFunction) => {
const currentUser: Users[] = await Users.findOne({
where: {
email: req.email,
},
}).then((r: any) => {
return r.user_id;
});
let pageNum = Number(res.req.query.pageCount);
let offset = 0;
if (pageNum > 1) {
offset = 10 * (pageNum - 1);
}
const selectCurrentTweets = await Tweets.findAll({
include: [Likes, Bookmark, Comments],
offset: offset,
limit: 10,
}).then((d: any) => {
return d.map((d: any) => {
let isLike = false;
//기본값은 false로 넘겨줌
let isBookmark = false;
if (
d.like.some((i: any) => {
return i.user_id === currentUser;
})
) {
isLike = true;
}
//트윗데이터중에서 현재 유저가 북마크를 한 데이터가 존재하는지 탐색 후 북마크된 데이터는 isBookmark를 true값으로 넘겨줌.
if (
d.bookmark.some((i: any) => {
return i.user_id === currentUser;
})
) {
isBookmark = true;
}
return {
tweet_id: d.tweet_id,
content: d.content,
email: d.email,
like: d.like,
tag: d.tag,
user_id: d.user_id,
write_date: d.write_date,
upload_file: d.upload_file,
reply_tweet_id: d.reply_tweet_id,
is_like: isLike,
is_bookmark: isBookmark,
comment: [],
is_opened: false,
retweet_opened: false,
};
let count = await Tweets.count();
let totalPageNumber = Math.round((await Tweets.count()) / 10);
res.status(200).json({
data: selectCurrentTweets,
count,
user_id: currentUser,
totalPageNumber: totalPageNumber,
});
}
);
bookmark 버튼 및 관련 함수
-> 북마크 유무에 따라 보여주는 아이콘과 클릭시 실행 함수 다르게 넣어주기.
<img
className="w-6 h-4 pl-2"
alt="#"
src={
t.is_bookmark
? "/assets/bookmark.png"
: "/assets/bookmark_before.png"
}
onClick={() => {
console.log("클릭!!!!!");
if (t.is_bookmark === true) {
deleteBookmark(t.tweet_id);
}
if (t.is_bookmark === false) {
addBookmark(t.tweet_id);
}
}}
/>
const deleteBookmark = (prop: number) => {
customAxios
.post("/saveBookmark/delete", {
tweet_id: prop,
id: id,
})
.then((res) => {
customAxios
.get("/getTweets/select", {
params: { getCurrentPage },
})
.then((result: any) => {
//데이터 업데이트 하기
queryClient.invalidateQueries(["select"]);
});
});
};
const addBookmark = (tweet_id: number) => {
customAxios
.post("/saveBookmark", {
tweet_id: tweet_id,
id: id,
})
.then((res) => {
customAxios
.get("/getTweets/select", {
params: { getCurrentPage },
})
.then((result: any) => {
queryClient.invalidateQueries(["select"]);
});
});
};
'sns 프로젝트' 카테고리의 다른 글
React 무한스크롤 구현하기(Intersection Observer) (0) | 2024.01.22 |
---|---|
페이지네이션 기능 구현하기 (0) | 2024.01.22 |
댓글 알림 리스트 기능 구현하기 (0) | 2024.01.22 |
게시물 좋아요 기능 구현하기 (0) | 2024.01.22 |
트위터 리트윗 기능 구현하기 (1) | 2024.01.22 |