개요
이 가이드 에서는 MERN 스택 사용하는 React 웹 애플리케이션 만드는 방법을 학습 수 있습니다. MERN 스택 MongoDB, Express, React 및 Node.js를 사용하는 웹 개발 프레임워크 이며 다음과 같은 계층으로 구성되어 있습니다.
데이터베이스 계층: MongoDB 데이터 저장 및 검색을 제공합니다.
애플리케이션 계층: Express 와 노드.js는 서버 측 로직의 중간 계층 구성합니다.
프레젠테이션 계층: React 사용자 인터페이스와 프론트엔드 상호 작용을 구현합니다.
React 애플리케이션에서 MongoDB 사용하는 이유는 무엇인가요?
React 애플리케이션 데이터를 MongoDB 에 저장하면 문서 데이터 모델 사용하여 복잡한 쿼리 표현식을 빌드 수 있습니다. 문서 모델의 유연성으로 중첩된 데이터 구조를 저장 하고 애플리케이션 설계를 빠르게 반복할 수 있습니다. MongoDB의 수평 확장 역량을 사용하여 애플리케이션 쉽게 확장할 수도 있습니다.
MongoDB 사용한 MERN 스택 동적이고 진화하는 데이터 구조가 필요한 애플리케이션을 지원합니다. 따라서 이 프레임워크 실시간 대시보드나 콘텐츠를 지속적으로 업데이트 한 페이지짜리 애플리케이션과 같은 실제 애플리케이션에 적합하게 설계되었습니다.
빠른 시작 튜토리얼
이 튜토리얼에서는 MERN 스택 사용하여 웹 애플리케이션 빌드 방법을 보여줍니다. 애플리케이션 샘플 레스토랑 데이터에 액세스하고, 데이터를 쿼리하고, 로컬에서 호스팅되는 사이트 에 결과를 표시합니다. 이 튜토리얼에는 MongoDB Atlas 에서 호스팅되는 MongoDB 클러스터 에 연결하고 데이터베이스 의 데이터에 액세스하고 표시하는 방법에 대한 지침도 포함되어 있습니다.
팁
React 없이 Node.js 드라이버를 사용하여 MongoDB에 연결하려는 경우 Node.js 드라이버 시작하기 가이드를 참조하세요.
프로젝트 설정
이 섹션의 단계에 따라 프로젝트 종속성을 설치하고, Atlas 클러스터를 만들고, 애플리케이션 디렉토리를 설정합니다.
전제 조건 확인
Quick Start 애플리케이션을 생성하려면 개발 환경에 다음 소프트웨어가 설치되어 있어야 합니다.
전제 조건 | 참고 사항 |
|---|---|
최신 LTS 또는 최신 릴리스 버전을 다운로드합니다. | |
코드 편집기 | 이 튜토리얼에서는 Visual Studio Code를 사용하지만 원하는 편집기를 사용할 수 있습니다. |
터미널 앱 및 shell | MacOS 사용자의 경우 터미널 또는 유사한 앱을 사용하세요. Windows 사용자의 경우 PowerShell을 사용하세요. |
MongoDB Atlas 클러스터 생성
MongoDB Atlas 는 MongoDB 배포서버를 호스팅하는 완전 관리형 클라우드 데이터베이스 서비스입니다. MongoDB 배포서버 없는 경우, MongoDB 시작하기 튜토리얼을 완료하여 무료로 MongoDB 클러스터 생성할 수 있습니다( 크레딧 카드 필요 없음). MongoDB 시작하기 튜토리얼에서는 이 튜토리얼에서 사용되는 sample_restaurants 데이터베이스 포함하여 샘플 데이터 세트를 클러스터 에 로드하는 방법도 보여줍니다.
MongoDB 클러스터에 연결하려면 연결 URI를 사용해야 합니다. 연결 URI를 조회 방법을 학습하려면 MongoDB 시작하기 튜토리얼의 연결 문자열 추가하기 섹션을 참조하세요.
중요
연결 string 을 안전한 위치 에 저장합니다.
package.json 파일 수정
react-quickstart/server 디렉토리 의 package.json 파일 로 이동합니다. 재사용을 위해 JavaScript 코드를 패키징하는 표준 형식인 ECMAScript 모듈을 사용하려면 "type" 필드 지정하는 기존 줄을 다음 줄로 바꾸세요.
"type": "module",
다음 명령을 실행하여 mongodb, express 및 cors 종속성을 설치합니다.
npm install mongodb express cors
이 명령은 MongoDB, Express 웹 프레임워크 및 교차 출처 리소스 공유 가능하게 하는 cors Node.js 패키지 설치합니다.
백엔드 구성
프로젝트 구조 및 종속성을 설정한 후 이 섹션의 단계에 따라 웹 서버 구성하고 MongoDB 에 연결합니다.
Express 웹 서버 구성
react-quickstart/server 디렉토리 에 server.js 라는 파일 만들고 다음 코드를 붙여넣습니다.
import express from "express"; import cors from "cors"; import restaurants from "./routes/restaurant.js"; const PORT = process.env.PORT || 5050; const app = express(); app.use(cors()); app.use(express.json()); app.use("/restaurant", restaurants); // start the Express server app.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); });
환경 변수 설정
server 디렉토리 에서 다음 변수를 저장하는 config.env 파일 만듭니다.
MONGODB_URI=<connection URI> PORT=5050
<connection URI> 자리 표시자를 이전 단계에서 저장한 연결 URI로 바꿉니다.
서버 API 엔드포인트 만들기
server 디렉토리 에서 routes이라는 하위 디렉토리를 만듭니다. routes 하위 디렉토리에 restaurant.js 라는 파일 만들고 다음 코드를 붙여넣습니다.
import express from "express"; import db from "../db/connection.js"; // Creates an instance of the Express router, used to define our routes const router = express.Router(); // Gets a list of all the restaurants router.get("/", async (req, res) => { let collection = await db.collection("restaurants"); let results = await collection.find({}).toArray(); res.send(results).status(200); }); // Lists restaurants that match the query filter router.get("/browse", async (req, res) => { try { let collection = await db.collection("restaurants"); let query = { borough: "Queens", name: { $regex: "Moon", $options: "i" }, }; let results = await collection.find(query).toArray(); res.send(results).status(200); } catch (err) { console.error(err); res.status(500).send("Error browsing restaurants"); } }); export default router;
이 파일 sample_restaurants 데이터베이스 의 restaurants 컬렉션 에 액세스하고 다음 GET 엔드포인트를 정의합니다.
/: 샘플 컬렉션 에서 모든 레스토랑을 조회합니다./browse: 쿼리 기준과 일치하는 레스토랑을 조회하며, 이름에"Moon"라는 단어가 포함된 퀸즈의 레스토랑을 필터링합니다.
프런트 엔드 구성
애플리케이션의 백엔드를 설정한 후 이 섹션의 단계에 따라 React 구성하고 프론트엔드 구성 요소를 추가합니다.
React 템플릿 추가
react-quickstart 디렉토리에서 다음 명령을 실행하여 Vite:를 사용하여 React 템플릿 파일을 추가합니다.
npm create vite@latest client
이 명령은 일련의 구성 질문에 응답하라는 메시지를 표시합니다. 각 질문에 대해 드롭다운 메뉴에서 다음 응답을 선택합니다.
프레임워크 선택 : React
변형 선택: JavaScript
Rolldown-vite(실험 단계)를 사용하시겠습니까?: 아니요
npm 으로 설치하고 지금 시작하시겠습니까?: 아니요
명령을 실행 하면 프로젝트 에 프런트엔드 스캐폴딩이 포함된 client 디렉토리 생깁니다.
Tailwind CSS 설치
이 샘플 애플리케이션 UI 서식 지정에 Tailwind CSS 프레임워크 사용합니다. 설치하려면 이전 단계에서 만든 client 디렉토리 로 이동하여 다음 명령을 실행 .
npm install tailwindcss @tailwindcss/vite
설치 후 vite.config.js 파일 로 이동합니다. 강조 표시된 줄에 표시된 대로 가져오기 문과 plugins 배열 업데이트하여 @tailwindcss/vite 플러그인을 추가합니다.
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import tailwindcss from '@tailwindcss/vite' // https://vite.dev/config/ export default defineConfig({ plugins: [ react(), tailwindcss() ], })
그런 다음 client/src/index.css 파일 로 이동하여 다음 가져오기 성명서 추가합니다.
@import "tailwindcss";
React 라우터 설정
client/src/main.jsx 파일 로 이동하여 다음 코드를 붙여넣습니다.
import * as React from "react"; import * as ReactDOM from "react-dom/client"; import { createBrowserRouter, RouterProvider } from "react-router-dom"; import App from "./App"; import RestaurantList from "./components/RestaurantList"; import "./index.css"; const router = createBrowserRouter([ { path: "/", element: <App />, children: [ { path: "/", element: <RestaurantList />, }, ], }, { path: "/browse", element: <App />, children: [ { path: "/browse", element: <RestaurantList />, }, ], }, ]); ReactDOM.createRoot(document.getElementById("root")).render( <React.StrictMode> <RouterProvider router={router} /> </React.StrictMode>, );
이 파일 클라이언트 사이드 라우팅을 구성하고 다음 경로를 정의합니다.
/:/restaurant/API 엔드포인트를 호출하여 모든 레스토랑을 표시하는RestaurantList구성 요소를 렌더링합니다./browse:/restaurant/browseAPI 엔드포인트를 호출하여 필터링된 레스토랑을 표시하는RestaurantList구성 요소를 렌더링합니다.
구성 요소 만들기
client 디렉토리 에서 다음 명령을 실행하여 두 개의 파일이 포함된 components 라는 새 폴더를 만듭니다.
mkdir src/components cd src/components touch Navbar.jsx RestaurantList.jsx
Navbar.jsx 파일 필수 구성 요소에 연결되는 탐색 모음을 구성합니다. 이 파일 에 다음 코드를 붙여넣습니다.
import { NavLink } from "react-router-dom"; export default function Navbar() { return ( <div> <nav className="flex justify-between items-center mb-6"> <NavLink to="/"> <img alt="MongoDB logo" className="h-10 inline" src="https://d3cy9zhslanhfa.cloudfront.net/media/3800C044-6298-4575-A05D5C6B7623EE37/4B45D0EC-3482-4759-82DA37D8EA07D229/webimage-8A27671A-8A53-45DC-89D7BF8537F15A0D.png" ></img> </NavLink> </nav> </div> ); }
RestaurantList.jsx 파일 레스토랑의 보기 구성 요소로, 레스토랑 정보를 검색하고 표시합니다. 이 파일 에 다음 코드를 붙여넣습니다.
import { useEffect, useState } from "react"; import { useLocation } from "react-router-dom"; const Restaurant = (props) => ( <tr className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted"> <td className="p-4 align-middle [&:has([role=checkbox])]:pr-0"> {props.restaurant.name} </td> <td className="p-4 align-middle [&:has([role=checkbox])]:pr-0"> {props.restaurant.borough} </td> <td className="p-4 align-middle [&:has([role=checkbox])]:pr-0"> {props.restaurant.cuisine} </td> </tr> ); export default function RestaurantList() { const [restaurants, setRestaurants] = useState([]); const location = useLocation(); // Fetches the restaurants from the database useEffect(() => { async function getRestaurants() { // Determines which endpoint to call based on current route const endpoint = location.pathname === "/browse" ? "http://localhost:5050/restaurant/browse" : "http://localhost:5050/restaurant/"; const response = await fetch(endpoint); if (!response.ok) { const message = `An error occurred: ${response.statusText}`; console.error(message); return; } const restaurants = await response.json(); setRestaurants(restaurants); } getRestaurants(); return; }, [location.pathname]); // Maps each restaurant on the table function restaurantList() { return restaurants.map((restaurant) => { return <Restaurant restaurant={restaurant} key={restaurant._id} />; }); } // Retrieves the dynamic title based on current route const getTitle = () => { return location.pathname === "/browse" ? 'Filtered Restaurants (Queens, containing "Moon")' : "All Restaurants"; }; // Displays the restaurants table return ( <> <h3 className="text-lg font-semibold p-4">{getTitle()}</h3> <div className="border rounded-lg overflow-hidden"> <div className="relative w-full overflow-auto"> <table className="w-full caption-bottom text-sm"> <thead className="[&_tr]:border-b"> <tr className="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted"> <th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0"> Name </th> <th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0"> Borough </th> <th className="h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0"> Cuisine </th> </tr> </thead> <tbody className="[&_tr:last-child]:border-0"> {restaurantList()} </tbody> </table> </div> </div> </> ); }
마지막으로 client/src/App.jsx 파일 로 이동합니다. 이 파일 기본 레이아웃 구성 요소이며 Navbar 구성 요소가 각 페이지 상단에서 하위 구성 요소 위에 렌더링되도록 합니다. 이 파일 에 다음 코드를 붙여넣습니다.
import { Outlet } from "react-router-dom"; import Navbar from "./components/Navbar"; const App = () => { return ( <div className="w-full p-6"> <Navbar /> <Outlet /> </div> ); }; export default App;
애플리케이션 실행하기
마지막으로 이 섹션의 단계에 따라 애플리케이션 실행 하고 렌더링된 레스토랑 데이터를 확인합니다.
애플리케이션 사이트 열기
이전 단계에서 조회한 http://localhost:5173/ URL 엽니다. 초기 방문 페이지에는 sample_restaurants.restaurants 컬렉션 의 모든 레스토랑 목록이 표시됩니다.

그런 다음 http://localhost:5173/browse URL 로 이동하여 name 및 borough 필드 쿼리 와 일치하는 레스토랑을 확인합니다.

빠른 시작 튜토리얼을 완료하신 것을 축하드립니다!
이 단계를 완료하면 MongoDB deployment 에 연결하고, 샘플 레스토랑 데이터에 대해 쿼리 실행하고, 검색된 결과를 렌더링하는 React 웹 애플리케이션 갖게 됩니다.
추가 리소스
React, MongoDB 및 MERN 스택 에 대해 자세히 학습 다음 리소스를 참조하세요.
React 문서
Express 문서
Node.js 운전자 문서