우리가 만들고 있는 것
방명록: React의 양식은 서버에 메시지를 보내고, 서버는 이를 저장하고, 향후 모든 방문자에게 보여줍니다. 아무 것도 보낼 곳이 없었던 레벨 2의 양식을 기억하시나요? 오늘 우리는 그 빚을 갚았어.
보여줄게: 방명록 백엔드
에서my-server폴더에 먼저 패키지를 하나 더 설치해.
npm install cors
그리고 편집server.js:
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors()); // allow the frontend on a different port to ask questions
app.use(express.json()); // understand JSON in incoming requests
const messages = [
{ name: "Martin", text: "First message! Long live the guestbook. 📖" },
];
// GET – hand out messages
app.get("/api/messages", (request, response) => {
response.json(messages);
});
// POST – accept a new message
app.post("/api/messages", (request, response) => {
const { name, text } = request.body;
// Never trust input: check it on the server too!
if (!name || !text || name.length > 50 || text.length > 500) {
return response.status(400).json({ error: "Invalid message." });
}
messages.push({ name, text });
response.json({ saved: true });
});
app.listen(3900, () => {
console.log("Server running at http://localhost:3900");
});
새로운 내용:
cors()– 프런트엔드는 포트 3901, 서버는 3900에서 실행돼. 브라우저는 일반적으로 이와 같은 “교차 출처” 요청을 차단해(CORS라는 보안 규칙). 이것이 서버에서 허용하는 방법야.app.post(...)– 첫 번째 POST 끝점! 양식 데이터가 다음에 표시돼.request.body.- 서버에서 확인 중 – 프런트엔드가 이미 양식을 확인했지만 공격자가 양식을 우회하여 직접 요청을 보낼 수 있어. 그렇기 때문에 철칙이 적용돼. 백엔드는 항상 확인하고 프런트엔드는 절대 신뢰하지 않어.
status(400)”잘못된 요청”을 의미해.
보여줄게: 방명록 프런트엔드
React 프로젝트에서 다음을 생성해.src/GuestBook.jsx:
import { useState, useEffect } from 'react';
function GuestBook() {
const [messages, setMessages] = useState([]);
const [name, setName] = useState("");
const [text, setText] = useState("");
// On first render: download the messages from the server
useEffect(() => {
fetch("http://localhost:3900/api/messages")
.then((response) => response.json())
.then((data) => setMessages(data));
}, []);
function submit(event) {
event.preventDefault();
fetch("http://localhost:3900/api/messages", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, text }),
})
.then((response) => response.json())
.then(() => {
setMessages([...messages, { name, text }]); // add it to the screen too
setName("");
setText("");
});
}
return (
<div>
<h2>Guestbook 📖</h2>
{messages.map((message, index) => (
<div className="card" key={index}>
<strong>{message.name}</strong>
<p>{message.text}</p>
</div>
))}
<form onSubmit={submit}>
<input
value={name}
onChange={(event) => setName(event.target.value)}
placeholder="Your name"
/>
<textarea
value={text}
onChange={(event) => setText(event.target.value)}
placeholder="Write a message..."
/>
<button type="submit">Send</button>
</form>
</div>
);
}
export default GuestBook;
React의 마지막 세 가지 새로운 기능:
useEffect(() => {...}, [])– “구성 요소가 처음 나타날 때 이 작업을 한 번 실행해.” 데이터를 다운로드하기에 이상적인 장소야.fetch~와 함께method: "POST"– 우리는 데이터를 보내고 있어.JSON.stringifyJSON으로 압축해.- 연결된 양식 – 필드는 상태에서 해당 값을 읽어(
value={name})를 입력하고 (onChange). 양식과 상태는 항상 동기화 상태를 유지해.
네 차례 💪
- 두 가지 모두 실행: 하나의 터미널에 있는 서버(
node server.js), 다른 하나에서는 반응(npm run dev -- --port 3901). 두 개의 터미널, 두 개의 프로그램 - 풀 스택에 오신 것을 환영해! - 추가
<GuestBook />앱에 추가하여 사용해 보세요. 메시지를 작성하고 페이지를 다시 로드해. – 메시지는 그대로 남아 있어(서버가 계속 실행되는 한). - 방명록을 프로젝트에 맞게 조정해. 🏫 학교 메시지 · 🙋 친구를 위한 메시지 보드 · 🌍 “어디로 가야 할까요?” 방문객의 팁 · ⚽ 팬들의 함성.
- 빈 메시지를 보내보세요. 프런트엔드에서는 이를 허용하지만(확인 없음) 서버에서는 이를 거부해. 그런 다음 프런트엔드에도 확인 표시를 추가하여 양식이 레벨 2와 마찬가지로 예의바릅니다.
💡
**서버가 다시 시작되면 메시지가 사라집니다** – 메시지는 메모리의 배열에만 존재해. 실제 응용 프로그램은 이를데이터 베이스, 무엇이든 살아남어. 이 레벨을 마친 후 가장 먼저 배워야 할 것은 키워드: SQLite, PostgreSQL야.
✅
**직접 확인해:** 양식의 메시지가 서버로 이동하여 저장되고 페이지가 다시 로드된 후 다시 나타나. 방금 구축한풀스택 애플리케이션– 프론트엔드, 백엔드, API. 이것이 바로 전문 개발자가 매일 하는 일야.
이번 수업에서 배울 점
-useEffect(..., [])첫 번째 렌더링 시 데이터를 다운로드해.fetchPOST로 보냅니다.
- 보안의 철칙: 프런트엔드가 확인할 때에도 서버는 모든 입력을 확인해.
- 풀 스택 = 실행 중인 두 프로그램(3901 + 3900)이 API를 통해 서로 통신해.
© 2026 Ing. Martin Polak / AlgoRhino · 콘텐츠 이용 약관