이제 홈 화면에서 더미 데이터가 아닌 MongoDB 데이터베이스에 있는 데이터들을 가져와서 보여주도록 하자.
이 작업 또한 새로운 API 라우트를 생성하고 handler 함수를 작성하여, API를 이용해 데이터를 fetch해오도록 할 수 있지만.. 이 방식은 불필요한 요청을 보내는 방식이다.
따라서 API 경로를 생성하고 요청을 보낼 필요 없이 그냥 getStaticProps()
함수 내에서 바로 데이터베이스에 연결하고, 데이터를 가져오는 코드를 작성하도록 한다.
// pages/index.js
import MeetupList from '../components/meetups/MeetupList';
function HomePage(props) {
return <MeetupList meetups={props.meetups} />;
}
export async function getStaticProps() {
// fetch('/api/meetups')... ❌
return {
props: {
meetups: DUMMY_MEETUPS, // 더미 데이터
},
};
}
export default HomePage;
new-meetup
페이지에서 했던 같은 방식으로 MongoDB 데이터베이스와 연결하고, meetupCollection
을 가져온다.
find()
메소드를 이용해 해당 컬렉션 안에 있는 모든 문서들을 가져올 수 있으며, toArray()
메소드로 배열 형태로 변환할 수 있다.
MongoDB의 각 문서들은 MongoDB에서 자체적으로 부여한 유니크한 값인 _id
필드를 가지게 되는데, 이 값은 ObjectId라는 특수한 객체로 표현된다. 따라서 toString()
메소드를 이용해 문자열로 변환해 사용해야 한다.
import MeetupList from '../components/meetups/MeetupList';
import { MongoClient } from 'mongodb';
function HomePage(props) {
return <MeetupList meetups={props.meetups} />;
}
export async function getStaticProps() {
const client = await MongoClient.connect('mongodb+srv://janechun22:janechun22@cluster0.jrwnfs4.mongodb.net/?retryWrites=true&w=majority');
const db = client.db();
const meetupCollection = db.collection('meetups');
const meetups = await meetupCollection.find().toArray();
client.close();
return {
props: {
meetups: meetups.map((meetup) => ({
id: meetup._id.toString(), // 문자열로 변환
title: meetup.title,
address: meetup.address,
image: meetup.image,
})),
},
};
}
export default HomePage;
meet up 게시글을 클릭하면 상세 페이지로 이동하게 된다.
이때 /id
경로로 이동되도록 하고, 상세 페이지에서는 params로 얻어온 id를 이용해 해당 id를 가진 값을 컬렉션에서 찾아 해당 문서 1개만 불러오도록 해보자.
getStaticPaths()
함수 내에서도 MongoDB에서 컬렉션을 불러오고 find()
메소드를 이용해 컬렉션 안의 문서를 불러올 수 있다.
이때, find()
메소드 안에 매개변수를 전달하여 컬렉션 안의 문서를 원하는 방식으로 필터링하여 불러올 수 있다.
아래 코드에서는 meetupCollection 컬렉션 안의 모든 문서를 가져오는데, 가져오는 문서들은 _id
필드만 포함하도록 필터링한다.
import React from 'react';
import MeetupDetail from '../../components/meetups/MeetupDetail';
import { MongoClient, ObjectId } from 'mongodb';
function MeetupDetails(props) {
return (
<MeetupDetail
// ...
/>
);
}
export async function getStaticPaths() {
const client = await MongoClient.connect('mongodb+srv://janechun22:janechun22@cluster0.jrwnfs4.mongodb.net/?retryWrites=true&w=majority');
const db = client.db();
const meetupCollection = db.collection('meetups');
const meetups = await meetupCollection.find({}, { _id: 1 }).toArray();
// {} ➡️ 필터 X, 모든 문서 불러옴
// {_id: 1} ➡️ _id 필드만 가져온다.
client.close();
return {
fallback: false,
paths: meetups.map((meetup) => ({ // id만 담고있는 meetups를 paths 형태에 맞게 가공해야 한다.
params: {
meetupId: meetup._id.toString(),
},
})),
};
}
findOne()
메소드를 이용해 컬렉션에서 문서 1개를 가져올 수 있다.
_id
필드가 params에서 받아온 meetupId
와 일치하는 조건은 아래처럼 입력하면 된다.
이때 문자열을 ObjectId 객체로 바꿔줘야 하므로 new ObjectId()
를 사용해야 한다.
export async function getStaticProps(context) {
const meetupId = context.params.meetupId; // params에서 받아온 meetupId
const client = await MongoClient.connect('mongodb+srv://janechun22:janechun22@cluster0.jrwnfs4.mongodb.net/?retryWrites=true&w=majority');
const db = client.db();
const meetupCollection = db.collection('meetups');
const selectedMeetup = await meetupCollection.findOne({ _id: new ObjectId(meetupId) }); //
return {
props: {
meetupData: {
id: selectedMeetup._id.toString(),
title: selectedMeetup.title,
image: selectedMeetup.image,
description: selectedMeetup.description,
},
},
};
}
export default MeetupDetails;
고생하셨습니다 혼자서 하시는건가요? 대단합니다 ㅎㅎ