클라이언트 사이드 렌더링을 사용해서 새로고침없이 댓글이 바로 나오게끔 만들어보자.
ajax 를 사용하려면 클라이언트 컴포넌트로 해야 사용해보자
아이템 디테일 폴더 안에 클라이언트 컴포넌트 파일생성.
'use client'
import { useState } from 'react';
const Comment = () => {
const [comment, setComment] = useState('')
return (
<div>
<div>댓글목록보여줄부분</div>
<input onChange={(e)=>{setComment(e.target.value)}}/>
<button onClick={()=>{
console.log(comment)
fetch('/URL',{method:'POST',body:comment})
}}>댓글전송</button>
</div>
);
};
export default Comment;
댓글을 적으면 데이터를 DB에 저장해야한다.
1.댓글 데이터의 id값
2.댓글 컨텐츠
3.작성자의 이메일
4.데이터가 어느 게시글에있는지 게시글의 id값
만든 코드
'use client'
import { useState } from 'react';
const Comment = ({itemId,email}:any) => {
const [comment, setComment] = useState({})
return (
<div>
<div>댓글목록보여줄부분</div>
<input onChange={(e)=>{setComment({content:e.target.value,perent:itemId,author:email})}}/>
<button onClick={()=>{
console.log(comment)
fetch('/api/post/comment',{method:'POST',body:JSON.stringify(comment)})
}}>댓글전송</button>
</div>
);
};
export default Comment;
프롭스 형식으로 스테이트에 넣어서 body로 api 에 전부 넘긴다.
여러개의 데이터를 넘길때는 body에 JSON.stringify() 로 넣어서 해야한다. (문자열 직렬화를 해서 보낸다.)
aip 데이터 받는곳.
import { connectDB } from '@/util/database';
const comment = async(요청:any,응답:any) => {
console.log(요청.body)
let result = await (await connectDB).db("forum").collection('comment').insertOne(JSON.parse(요청.body));//insertOne는 데이터를 db에 보내서 저장시키는 명령어
};
export default comment;
데이터를 받아서 저장해준다. 저장할때 역 직렬화로 해서 보내야 저장이된다.
JSON.parse() 역직렬화를 위해 사용해야하는 메서드.
상세페이지에 댓글을 작성할 수 있는 기능을 만들어봅시다.
댓글 조회기능과 댓글 발행기능 만들어놓으면 끝인데
근데 server-side rendering은 지겨우니
이번엔 client-side rendering을 해보도록 합시다.
client-side rendering 하면 브라우저에서 html 생성, 수정, 삭제를 해줄 수 있기 때문에
부드럽고 이쁜 사이트를 만들 수 있지만 검색노출은 잘 안될 수 있습니다.
근데 댓글이라 검색노출 잘 안되어도 상관없을듯요
그럼 댓글 발행기능부터 만들어볼건데
1. 유저가 댓글쓰고 전송버튼누르면
2. 서버로보내서 DB에 댓글을 저장하기
그냥 이거 코드로 옮기면 끝이겠군요.
댓글 UI 만들기
자바스크립트를 써서 html을 생성 수정 삭제하고 싶으니까
댓글넣을 부분은 client component로 만들어봅시다.
(Comment.js)
'use client'
export default function Comment(props) {
return (
<div>
<div>댓글목록</div>
<input />
<button>댓글전송</button>
</div>
)
}
(/detail/[]/page.js)
import Comment from './Comment.js'
export default async function Detail(props) {
return (
<div>
(생략)
<Comment/>
</div>
)
}
상세페이지 옆에 <Comment/>라는 컴포넌트를 만들어서 상세페이지에 집어넣어봤습니다.
이제 전송버튼누르면 서버로 댓글작성한걸 보내고 DB에 저장해보면 끝인데
그 전에 리액트에서 <input> 에 입력한 값 다루는 법을 알아봅시다.
input에 적은 내용 가져오기
리액트에서 <input>안에 입력한 값을 사용하고 싶으면 <form> 쓰면 되는데
이걸 사용할 경우 새로고침되는게 싫고 ajax로 보내고 싶으면
보통 state에 넣어두고 사용합니다.
(Comment.js)
'use client'
import {useState} from 'react'
export default function Comment(props) {
let [comment, setComment] = useState('')
return (
<div>
<div>댓글목록</div>
<input onChange={(e)=>{ e.target.value }} />
<button>댓글전송</button>
</div>
)
}
client component에서 유저가 <input>에 적은 내용 가져오려면
1. onChange라는 이벤트핸들러 안에서 e.target.value 라고 쓰면 유저가 입력한 값이 들어있습니다.
2. 그걸 보통 state에 저장해두고 사용합니다. 그래서 state 만들고 거기 e.target.value 넣었음
onChange 안의 코드는 input에 뭐 입력할 때 마다 실행되기 때문에
이제 입력할 때 마다 입력한 값이 state에 저장됩니다.
버튼누르면 서버로 댓글전송해보자
export default function Comment(props) {
let [comment, setComment] = useState('')
return (
<div>
<div>댓글목록</div>
<input onChange={(e)=>{ e.target.value }} />
<button onClick={()=>{ fetch('/URL', { method : 'POST', body : comment } ) }}>댓글전송</button>
</div>
)
}
이제 POST요청 받으면 DB에 댓글 저장해주는 서버기능 만들면 끝입니다.
근데 댓글을 DB 어디에 어떻게 저장할 것임?
대충 저장하면 나중에 고생할 수 있으니 잘 생각해봅시다.
DB 어디에 저장하냐면

▲ 당연히 글 document 안에 이렇게 댓글들을 저장하면 됩니다.
(document 안에 넣을 게 많으면 array 도 집어넣을 수 있습니다)
근데 문제점은 댓글이 1억개 달리면 어쩔 것입니까 그런 것도 생각해봅시다.
- MongoDB document 하나는 최대 8MB의 데이터를 저장할 수 있고
- array 안의 데이터들이 너무 많으면 거기서 원하는 것만 찾아서 수정, 삭제가 어려울 수 있습니다.
이런 이유 때문에 document 하나에 많은거 몰아넣으면 document 터져 죽음

▲ 그래서 이것처럼 collection 따로 만들어서 댓글하나를 document로 저장해놓는 것도 좋습니다.
근데 이런 정보만 넣으면 어디 달린 댓글인지 모르니까 ...

▲ 원래 어떤 글에 달린 댓글인지 표기하기 위해
부모 글의 _id 같은 것도 기록해두면 좋겠군요.
Q. DB에 뭔가 저장할 때 이렇게 해도 될지 모르겠어요
- 나중에 데이터가 많아져도 저장, 수정, 삭제, 출력이 잘 되면 잘 저장한 것입니다.
데이터가 많아졌을 때 수정, 삭제, 출력이 어려울 것 같으면 다른 document로 빼보십시오.
오늘의 숙제 :
댓글 전송버튼 누르면 DB에 댓글이 저장되는 기능을 만들어봅시다.
저장시 comment라는 이름의 collection에 저장하는게 어떨까요.
'Next' 카테고리의 다른 글
next13 댓글 불러오기 - 2.2var (0) | 2023.07.25 |
---|---|
next13 댓글기능 만들기 2 (0) | 2023.07.24 |
next13 회원가입기능 만들어서 사용하는법 (0) | 2023.07.05 |
next13 삭제시 로그인확인 과 당사자 확인하는법. (0) | 2023.07.03 |
next13 회원기능 만들기 : OAuth + session방식 사용하기 (0) | 2023.07.03 |