구현 해야할 목록
1. 사용자 별 댓글 등록
2. 답 댓글
3. 사용자 별 댓글 수정/ 삭제
page컴포넌트에서 댓글 등록 구현
Comment컴포넌트
const userComments = useSelector(
(state: any) => state.boardPageComment.boardComment
);
const userPageComment = userComments[boardId];
return(
<Comment userPageComment={userPageComment} />
);
state에서 commentSlice 가져온 후 페이지 id 적용
전체 코드
import React, { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import userComment from "../../redux/thunks/boardCommentThunk";
import { getAuth } from "firebase/auth";
import { useParams } from "react-router-dom";
const Comment = (props: any) => {
//댓글 내용
const [content, setConent] = useState("");
//사용자 정보
const auth = getAuth();
const currentUser = auth.currentUser;
const userId = currentUser?.uid;
const dispatch = useDispatch();
const selectedBoardId = useSelector(
(state: any) => state.board.selectedBoardId
);
const userNicNameList = useSelector((state: any) => state.login.userLists);
const userInformation = useSelector((state: any) => state.login.user);
const userNicName = userInformation.displayName;
//댓글 등록
const handleComment = async (e: any) => {
e.preventDefault();
// if (!!content) {
// window.confirm("댓글 내용을 입력 해주세요");
// return;
// }
const comment = {
content: content,
userUid: userId as string,
timedata: new Date(),
displayName: userNicName,
};
await dispatch(
userComment({
boardId: selectedBoardId,
boardComment: comment,
}) as any
);
setConent("");
};
const objectComment = Object.values(props);
return (
<div className="comment_box">
<form onSubmit={handleComment}>
<textarea
value={content}
maxLength={300}
onChange={(e) => {
setConent(e.target.value);
}}
placeholder="내용을 입력 해주세요"
/>
<input type="submit" value="등록" />
</form>
<div className="comment_view">
<div className="comment_user">
<ul>
{objectComment.map((items: any, index: number) =>
items.map((item: any, innerIndex: number) => {
return (
<li key={index}>
<span>{item.displayName}</span>
<span>{item.timedata}</span>
<div>{item.content}</div>
<div className="comment_txt">
<div className="comment_btn">
<input type="submit" value="댓글" />
<input type="submit" value="수정" />
<input type="button" value="삭제" />
</div>
</div>
</li>
);
})
)}
</ul>
</div>
</div>
</div>
);
};
export default Comment;
파이어베이스와 slice 연동 데이터가 등록 되는 것 확인
import { createSlice } from "@reduxjs/toolkit";
import userComment from "../thunks/boardCommentThunk";
interface CommentType {
content: string;
userUid: string;
timedata: Date;
displayName: string;
}
interface MyComment {
boardComment: Record<number, CommentType[]>;
}
const initialState: MyComment = {
boardComment: {},
};
const boardPageComment = createSlice({
name: "pageComment",
initialState,
reducers: {},
extraReducers: (builder) => {
builder
.addCase(userComment.pending, (state, action) => {
console.log(`비동기 댓글 요청 중`);
})
.addCase(userComment.fulfilled, (state, action) => {
console.log(`비동기 댓글 요청 성공`);
//1.
const { boardId, boardComment: pageComment } = action.payload;
//2.
const comment = state.boardComment[boardId] || [];
//3.
const newComment = [...comment, pageComment];
//4.
state.boardComment[boardId] = newComment;
})
.addCase(userComment.rejected, (state, action) => {
console.log(`비동기 댓글 실패`);
});
},
});
export default boardPageComment.reducer;
import { createAsyncThunk } from "@reduxjs/toolkit";
import { firestore } from "../../firebase";
import {
addDoc,
setDoc,
collection,
getDocs,
getDoc,
doc,
} from "firebase/firestore";
import { getAuth } from "firebase/auth";
interface CommentType {
content: string;
userUid: string;
timedata: Date;
displayName: string;
}
const userComment = createAsyncThunk<
{ boardId: number; boardComment: CommentType },
{ boardId: number; boardComment: CommentType }
>("user/comment", async (data, thunkAPI) => {
try {
const { boardId, boardComment } = data;
const { content } = boardComment;
const auth = getAuth();
const currentUser = auth.currentUser;
const userId = currentUser?.uid;
const state: any = thunkAPI.getState();
const boardSelectedId = state.board.selectedBoardId;
const strId = data.boardId.toString();
const userNicNameList = state.login.userLists;
const userInformation = state.login.user;
const userNicName = userInformation.displayName;
console.log(userNicName);
//컬렉션
const userCollection = collection(firestore, "users");
//도큐멘트
const userDocRef = doc(userCollection, "userData");
//컬렉션>도큐멘트>userId이름을 가진 하위 컬렉션
const subCollectionRef = collection(userDocRef, strId);
//하위 컬렌션이 가진 모든 하위 도큐멘트 출력 getDocs사용
const specificDoc = await getDocs(subCollectionRef);
for (const [index, docI] of specificDoc.docs.entries()) {
const data = docI.data();
const dataId = data.did;
const dataIndex = data.index;
//하위 도큐멘트
const docRef = doc(subCollectionRef, dataIndex);
//하위 컬렉션
const lastCallectionRef = collection(docRef, "comment");
if (boardSelectedId === dataId) {
// const underSetDoc = doc(lastCallectionRef, userId as string);
await addDoc(lastCallectionRef, {
content: content,
userUid: userId,
timedata: new Date(),
displayName: userNicName,
});
} else {
console.log("댓글 오류------------------");
}
}
const responseDataComment = {
boardId: boardSelectedId,
boardComment: {
content: content,
userUid: userId as string,
timedata: new Date(),
displayName: userNicName,
},
};
return responseDataComment;
} catch (error) {
throw error;
}
});
export default userComment;