컴퓨터 프로그래밍/Next.js

[Next.js] Dynamic route, useRouter()

한33 2025. 4. 22. 16:58

💡 Dynamic route 를 활용한 게시글 조회

https://hanstory33.tistory.com/293

 

위 링크처럼 게시글 당 id 가 있고 게시글 목록에서 제목 클릭 시에 해당 id 게시글의 상세 페이지로 이동시키고자 했다.

import {connectDB} from "@/util/database";
import Link from "next/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((item, index) =>
                <div className="list-item" key={index}>
                    <Link href={`/detail/${item._id}`}>
                        {item.title}
                    </Link>
                    <p>{item.content}</p>
                </div>
            )}
        </div>
    )
}

 

db 에서 게시글 전체를 가져오고 map 반복문을 통해 모든 게시글들을 불러와 조회시켰다.

a 태그와 Link 컴포넌트를 활용해서 해당 게시글 상세페이지로 이동을 시킬 수 있는데 여기에는 차이가 존재한다.

 

클라이언트 사이드 라우팅을 통해 웹을 새로고침 하는 것이 아닌 기존 SPA 스타일을 유지하는 Link 컴포넌트를 활용해서 해당 상세페이지로 이동시키도록 했다.

 

 

위처럼 detail 패키지 안에 [id] 패키지를 만들고 그 안에 page.js 파일을 만들면 detail/~~ 이런 식으로 접근이 가능하다.

export default async function Detail(props) {

    const db = (await connectDB).db("forum")
    let result = await db.collection('post').findOne({ _id : new ObjectId(props.params.id)})
    console.log(result)

    return (
        <div>
            <h4>상세페이지</h4>
            <h4>{result.title}</h4>
            <p>{result.content}</p>
        </div>
    );
}

 

이후 props 를 전달하면 props.params.id 에 해당 id 가 담겨서 db 로 부터 해당 id 를 가지고 있는 데이터 하나를 조회할 수 있다.

이를 result 에 담고 html 코드에서 result.title, result.content 를 불러와서 출력할 수 있다.

 

💡 useRouter

useRouter() 를 사용하면 자바스크립트 코드로 페이지이동을 시켜줄 수 있다.

다만 use~ 문법들은  client component 안에서만 쓸 수 있으니 client component 하나를 만들어서 진행해보았다.

 

list>DetialLink.js

'use client'

import {useRouter} from "next/navigation";

export default function DetailLink() {
    let router = useRouter()
    return (
        <button onClick={()=>{ router.push('/') }}>버튼</button>
    )
}

 

해당 컴포넌트에 'use client' 를 상단에 붙여주고 router 변수를 만들어서 useRouter() 를 사용할 준비를 해줬다.

 

  • router.back() : 뒤로가기
  • router.forward() : 앞으로 가기
  • router.push('/') : 해당 링크로 이동
  • router.refresh() : 새로고침. 하지만 페이지를 처음부터 로드하는 것이 아니라 이전과 바뀐 점만 새로고침 ( soft refresh )
  • router.prefetch('/') : prefetch 를 사용하면 해당 url 로 이동을 빠르게 하기 위해 필요한 데이터들을 미리 로드한다. 하지만 이는 Link Component 에 이미 실려있는 기능이기 때문에 Link 컴포넌트로 대체할 수 있다.
<Link href={'/어쩌구'} prefetch={false}>링크</Link> 

 

만약 그렇게 하기 싫으면 Link 컴포넌트에 prefetch 속성을 false 로 설정해주면 된다.

링크가 많은 게시판의 경우는 모든 링크를 다 읽을 것이 아닌데 굳이 다 미리 로드하는 것은 자원낭비이다.

 

또한 다양한 use~  기능들이 있는데

  • usePathname() : 현재 URL 출력
  • useSearchParams() : serch parameter 를 출력
  • useParams() : [dynamic route] 에 입력한 내용 ( URL Parameter ) 를 출력해준다.