🦷
[React] 댓글창 만들기
November 20, 2022
상세페이지에 Toast-UI 에디터를 사용해서 댓글 기능을 적용했다.
Editor 설치
리액트에서 사용하기 때문에 toast ui editor의 React Wrapper 버전을 설치
npm install @toast-ui/react-editor
1. 댓글 작성하기
// Comment.js
import { Button, Paper } from '@mui/material';
import '@toast-ui/editor/dist/toastui-editor.css';
import { Editor } from '@toast-ui/react-editor';
import SkeletonComment from '../../components/Skeleton/SkeletonComment';
const onSubmit = async (e) => {
e.preventDefault();
// 값 가져오기
const editorInstance = editorRef.current.getInstance();
// 마크다운 텍스트를 추출해주는 내장 메서드 getMarkdown() 이용
const getContent = editorInstance.getMarkdown();
setDisplay(!display);
setComment([
...comment,
{
replyContent: getContent,
replyId: id,
memberId: memberId,
nickname: user,
createdAt: `${date}`,
modifiedAt: `${date}`,
responseTo: 'root',
exist: true,
},
]);
const addComment = {
replyContent: getContent,
replyId: id,
memberId: memberId,
nickname: user,
createdAt: `${date}`,
modifiedAt: `${date}`,
responseTo: 'root',
exist: true,
};
await axios.post(`${process.env.REACT_APP_API_URL}reply/` + id, addComment);
await axios.get(`${process.env.REACT_APP_API_URL}reply/` + id).then((result) => {
setComment(result.data.data);
});
};
const onclickHandler = () => {
if (memberId) {
setDisplay(!display);
} else if (!memberId) {
alert('로그인이 필요합니다.');
navigate('/login');
}
};
return (
<>
{loading && <SkeletonComment />}
{!loading && (
<Paper sx={{ mt: 1, mb: 10, width: 690 }}>
<Button
onClick={() => onclickHandler()}
sx={{
width: '5.5rem',
fontSize: 12,
}}
>
댓글 작성
</Button>
{display && (
<>
{/* toast editor */}
<Editor ref={editorRef} />
<div>
<Button sx={{ color: '#afafaf' }} onClick={onSubmit}>
저장
</Button>
</div>
</>
)}
</Paper>
)}
</>
);
로그인 했을 때 댓글 작성 버튼을 누르면 toast editor가 나타나지만,
회원 정보가 없다면, 로그인 페이지로 이동시킨다.
2. 댓글 수정 & 삭제
import '@toast-ui/editor/dist/toastui-editor.css';
import { Editor } from '@toast-ui/react-editor';
// 댓글 수정
const onEdit = async ({ replyId }) => {
const editorInstance = editorRef.current.getInstance();
const getContent = editorInstance.getMarkdown();
setComment([
{
replyContent: getContent,
replyId: id,
memberId: memberId,
nickname: user,
createdAt: `${date}`,
modifiedAt: `${date}`,
responseTo: 'root',
exist: false,
},
]);
const editComment = {
replyContent: getContent,
replyId: id,
memberId: memberId,
nickname: user,
createdAt: `${date}`,
modifiedAt: `${date}`,
responseTo: 'root',
exist: false,
};
// ui는 잘 됨,
await axios.patch(`${process.env.REACT_APP_API_URL}reply/` + replyId, editComment).then(() => {
setComment(comment);
});
await axios.get(`${process.env.REACT_APP_API_URL}reply/` + id).then((result) => {
setComment(result.data.data);
});
};
// 댓글 삭제
const onRemove = async ({ replyId }) => {
await axios.delete(`${process.env.REACT_APP_API_URL}reply/` + replyId);
await axios.get(`${process.env.REACT_APP_API_URL}reply/` + id).then((result) => {
setComment(result.data.data);
});
};
return (
<>
{/* comment 수정 */}
{comment.memberId === memberId && (
<>
{openEditor === comment.replyId && <Editor value={comment.replyContent} ref={editorRef} />}
<Button
sx={{ color: '#afafaf', fontSize: 12 }}
onClick={() => {
if (comment.replyId === openEditor) {
onEdit(comment);
setOpenEditor('');
} else {
setOpenEditor(comment.replyId);
}
}}
>
수정
</Button>
{/* comment 삭제 */}
<Button
sx={{ color: '#afafaf', fontSize: 12 }}
onClick={() => {
onRemove(comment);
}}
>
삭제
</Button>
</>
)}
</>
);
결과 화면
댓글 작성, 수정, 삭제 권한은 오직 자신만 할 수 있도록 설정해놓았다.
추후 대댓글 기능 넣어보면 좋을 것 같다.