상세 페이지 (detail) 만들기
- 리스트 페이지에서 글 클릭하면 나오는 상세페이지 구현하기
1. 글 제목을 누르면
2. 상세페이지로 이동하고
3. 그 페이지에선 DB에서 그 게시물을 가져와서 보여줌
Dynamic route 사용
폴더 하나로 수많은 URL 생성
/detail/1로 접속시 1번글 내용
/detail/2로 접속시 2번글 내용
/detail/3로 접속시 3번글 내용
이렇게 보여줘야 함.
1) detail (상세페이지 URL) 폴더 하나 생성.
그리고 detail 폴더 안에 [작명] 해서 또 폴더 생성하기.
detail 폴더 안에 - [id] 폴더
- id 라고 작명했다.
- 대괄호 써줘야 함.
- URL 주소창 에다가 /detail/아무거나 입력했을 때 뜬다는 의미.
2) 그 다음 또 [작명] 폴더 안에다가 page.js 파일을 생성해줌
- URL 주소창 에다가 /detail/아무거나 입력했을 때
page.js 에 있는 페이지 내용 보여짐.
3) 생성한 page.js 에다가 컴포넌트를 만들어줘서 접속 시 보여지게끔 만들기.
export default async function Detail() {
return (
<div>
<h4>상세페이지임</h4>
<h4>글제목</h4>
<p>글내용</p>
</div>
)
}}
컴포넌트 생성해줌
4) 게시물 하나씩만 MongoDB에서 찾아서 갖고와서 보여주려면
= 저번시간에 한 몽고DB 코드갖고오는 코드 갖고오기.
const db = (await connectDB).db("forum");
let result = await db.collection("post").find().toArray();
DB 갖고 오는 코드를 갖고온다.
= post 컬렉션 안에 있는 모든 document(파일) 을 갖고오라는 코드.
import { connectDB } from "@/util/database"
export default async function Detail() {
const db = (await connectDB).db("forum");
let result = await db.collection("post").find().toArray();
return (
<div>
<h4>상세페이지임</h4>
<h4>글제목</h4>
<p>글내용</p>
</div>
)
}}
- connectDB 임포트 필수
- await 쓸 거니까 export default 옆에 에다가 async 써주기.
5) 게시물 하나만 갖고오도록 하기
= findOne() 사용
= id를 갖고오게 하기. (ObjectId)
const db = (await connectDB).db("forum");
let result = await db.collection("post").findOne({})
중괄호 열어줘서
갖고 올 document 의 내용 일부를 적어줌
db.collection(컬렉션명).findOne(찾을document내용)
console.log(result) 로 몽고DB 에서 뭘 갖고오는 지 확인 가능.
ObjectId 를 갖고오도록 하기.
import { ObjectId } from "mongodb";
import { connectDB } from "@/util/database.js"
export default async function Detail() {
let db = (await connectDB).db('forum')
let result = await db.collection('post').findOne({_id : new ObjectId('63ce8d2b10e3e9fd2d7e0c0b')});
console.log(result)
return (
<div>
<h4>상세페이지임</h4>
<h4>{result.title}</h4>
<p>{result.content}</p>
</div>
)
}}
※ObjectId 사용하려면 상단에 import 필수
※그리고 ObjectId 옆에 new 라는 거 써야함.
6) 유저가 URL 에 입력한 값 넣어줘서 유동적으로 페이지 보여주기
= props 활용
/detail/1 접속하면 1번게시물
/detail/2 접속하면 2번게시물
가져오라고 코드 수정
import { ObjectId } from "mongodb";
import { connectDB } from "@/util/database.js"
export default async function Detail(props) {
let db = (await connectDB).db('forum')
let result = await db.collection('post').findOne({_id : new ObjectId('63ce8d2b10e3e9fd2d7e0c0b')});
console.log(props)
return (
<div>
<h4>상세페이지임</h4>
<h4>{result.title}</h4>
<p>{result.content}</p>
</div>
)
}}
- Detail 옆 소괄호에 props 를 파라미터로 입력.
- 그리고 props 를 출력하면 URL 경로 자리에 입력한 값들이 터미널에 뜬다.
- [id] 로 작명해줬는데 대괄호 자리에 입력한 값을 출력해주는 것.
/detail/[id]
let result = await db
.collection("post")
.findOne({ _id: new ObjectId(props.params.id) });
- 유저가 입력한 값만 꺼내고 싶은경우엔
.params.id 라고 쓰면 bbb가 출력.
= 오브젝트 자료형 {} 안에 또 오브젝트 자료형 {}이 있는 형태이기 때문.
= props.params.id 이렇게 넣어줌.
list 페이지의 글 제목에 상세페이지 이동링크 생성하기
/detail/게시물의_id 이렇게 이동시켜주는 이동링크 생성
= Link 컴포넌트 사용
글 누르면 상세페이지로 이동시켜주는
= (/detail/게시물의_id ) 이 URL 로 이동시켜주는 링크 만들어주기.
1) Link 태그 사용하기
- import 필수
- list / page.js 에다가 해줌.
import { connectDB} from "@/util/database"
import Link from "next/link" //Link 태그 임포트
export default async function List(){
const db = (await connectDB).db("forum");
let result = await db.collection("post").find().toArray();
return (
<div className="list-bg">
{ result.map((a, i)=>
<div className="list-item" key={i}>
<h4>{result[i].title}</h4>
<Link href={"경로"}>링크</Link>
<p>1월 1일</p>
</div>
) }
</div>
)
}
<Link href = {"경로"}> 링크 </Link>
= /detail 하고 /글 id 를 경로로 작성.
2) /detail 하고 /글 id
글 id 경로 찾기
= result 변수 활용
const result = await db.collection('post').find().toArray();
여기 result 에 글 id 경로가 있음.
<h4>{result[i]._id}</h4>
h4 를 통해서 출력해보면
이렇게 글의 id 가 뜨는 거 확인.
= result[0].title 이렇게 써서 title 속성 빼오듯이 _id 속성을 빼오는 것
즉, result[i]._id는 i번째 게시물 객체에서 _id라는 속성의 값을 가져오는 코드
[
{ _id: "123", title: "첫 번째 게시물", content: "..." },
{ _id: "456", title: "두 번째 게시물", content: "..." },
{ _id: "789", title: "세 번째 게시물", content: "..." }
]
result의 생김새
3) 글의 id 를 찾았으면 Link 태그의 경로를 지정해주기
- 변수 사용 시 + 써서 연결
<Link href={"경로"}>링크</Link>
경로 넣는 곳에
<Link href={"/detail/result[i]._id"}>링크</Link>
이렇게 찾은 글의 id 를 넣어주면 될 것 같지만
result 는 변수니까 저런 식으로 쓰면 안된다.
<Link href={'/detail/' + result[i]._id}>링크</Link>
+ 써서 변수와 연결시켜줌.
4) 링크 경로 연결을 다 해줬으면 제목과 합쳐서
제목을 누르면 저 페이지로 이동하게끔 만들기.
제목인 h4 태그
<Link href={'/detail/' + result[i]._id}><h4>{a.title}</h4></Link>
Link 태그와 합쳐주기.
5) Link 태그 사용시
prefetch 기능 끄고 싶은 경우, false 로 사용해준다.
<Link href={'/어쩌구'} prefetch={false}>링크</Link>
Link 태그는 prefetch 기능이 default 로 들어가있음
Link 태그 외에 UseRouter 쓰는 방법도 존재
= client component 에서만 가능
= 자바스크립트 코드로 페이지이동
상단에
'use client' 써서 UseRouter 사용 가능
다양한 기능 존재.
서버 컴포넌트에서도 사용하려면
클라이언트 컴포넌트를 하나 만든 다음,
useRouter 기능을 넣고,
이 컴포넌트를 서버 컴포넌트에 집어넣는 식으로 하기.
'> 메모 > Next.js' 카테고리의 다른 글
[Next.js] 수정 기능 만드는 방법 (0) | 2024.11.14 |
---|---|
[Next.js] 글 작성 기능 만드는 방법 (5) | 2024.11.14 |
[Next.js] 글 목록 조회 (리스트 페이지) 만드는 방법 (2) | 2024.11.13 |
[Next.js] MongoDB 사용법 (0) | 2024.11.13 |
[Next.js] 리액트와 동일한 map () / 컴포넌트 / props (1) | 2024.11.12 |