FE develop/React
React로 HTTP 요청 보내기 - (1)
hoj0806
2025. 3. 12. 12:39
리액트로 HTTP 요청을 보내보자
백엔드는 Node를 사용했다
import fs from "node:fs/promises";
import bodyParser from "body-parser";
import express from "express";
const app = express();
app.use(express.static("images"));
app.use(bodyParser.json());
// CORS
app.use((req, res, next) => {
res.setHeader("Access-Control-Allow-Origin", "*"); // allow all domains
res.setHeader("Access-Control-Allow-Methods", "GET, PUT");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
next();
});
app.get("/places", async (req, res) => {
const fileContent = await fs.readFile("./data/places.json");
const placesData = JSON.parse(fileContent);
res.status(200).json({ places: placesData });
});
app.get("/user-places", async (req, res) => {
const fileContent = await fs.readFile("./data/user-places.json");
const places = JSON.parse(fileContent);
res.status(200).json({ places });
});
app.put("/user-places", async (req, res) => {
const places = req.body.places;
await fs.writeFile("./data/user-places.json", JSON.stringify(places));
res.status(200).json({ message: "User places updated!" });
});
// 404
app.use((req, res, next) => {
if (req.method === "OPTIONS") {
return next();
}
res.status(404).json({ message: "404 - Not Found" });
});
app.listen(5000);
백엔드 코드로 5000번대 포트에서 실행하게 된다
import { useEffect, useState } from "react";
import Places from "./Places.jsx";
export default function AvailablePlaces({ onSelectPlace }) {
const [availablePlaces, setAvailablePlaces] = useState([]);
return (
<Places
title='Available Places'
places={availablePlaces}
fallbackText='No places available.'
onSelectPlace={onSelectPlace}
/>
);
}
장소 데이터를 받아와 Places 컴포넌트에 넘겨줘야한다
[
{
"id": "p1",
"title": "Forest Waterfall",
"image": {
"src": "forest-waterfall.jpg",
"alt": "A tranquil forest with a cascading waterfall amidst greenery."
},
"lat": 44.5588,
"lon": -80.344
},
{
"id": "p2",
"title": "Sahara Desert Dunes",
"image": {
"src": "desert-dunes.jpg",
"alt": "Golden dunes stretching to the horizon in the Sahara Desert."
},
"lat": 25.0,
"lon": 0.0
},
{
"id": "p3",
"title": "Himalayan Peaks",
"image": {
"src": "majestic-mountains.jpg",
"alt": "The sun setting behind snow-capped peaks of majestic mountains."
},
"lat": 27.9881,
"lon": 86.925
},
{
"id": "p4",
"title": "Caribbean Beach",
"image": {
"src": "caribbean-beach.jpg",
"alt": "Pristine white sand and turquoise waters of a Caribbean beach."
},
"lat": 18.2208,
"lon": -66.5901
},
{
"id": "p5",
"title": "Ancient Grecian Ruins",
"image": {
"src": "ruins.jpg",
"alt": "Historic ruins standing tall against the backdrop of the Grecian sky."
},
"lat": 37.9715,
"lon": 23.7257
},
{
"id": "p6",
"title": "Amazon Rainforest Canopy",
"image": {
"src": "rainforest.jpg",
"alt": "Lush canopy of a rainforest, teeming with life."
},
"lat": -3.4653,
"lon": -62.2159
},
{
"id": "p7",
"title": "Northern Lights",
"image": {
"src": "northern-lights.jpg",
"alt": "Dazzling display of the Northern Lights in a starry sky."
},
"lat": 64.9631,
"lon": -19.0208
},
{
"id": "p8",
"title": "Japanese Temple",
"image": {
"src": "japanese-temple.jpg",
"alt": "Ancient Japanese temple surrounded by autumn foliage."
},
"lat": 34.9949,
"lon": 135.785
},
{
"id": "p9",
"title": "Great Barrier Reef",
"image": {
"src": "great-barrier-reef.jpg",
"alt": "Vibrant coral formations of the Great Barrier Reef underwater."
},
"lat": -18.2871,
"lon": 147.6992
},
{
"id": "p10",
"title": "Parisian Streets",
"image": {
"src": "parisian-streets.jpg",
"alt": "Charming streets of Paris with historic buildings and cafes."
},
"lat": 48.8566,
"lon": 2.3522
},
{
"id": "p11",
"title": "Grand Canyon",
"image": {
"src": "grand-canyon.jpg",
"alt": "Expansive view of the deep gorges and ridges of the Grand Canyon."
},
"lat": 36.1069,
"lon": -112.1129
},
{
"id": "p12",
"title": "Venetian Canals",
"image": {
"src": "venetian-canals.jpg",
"alt": "Glistening waters of the Venetian canals as gondolas glide by at sunset."
},
"lat": 45.4408,
"lon": 12.3155
},
{
"id": "p13",
"title": "Taj Mahal",
"image": {
"src": "taj-mahal.jpg",
"alt": "The iconic Taj Mahal reflecting in its surrounding waters during sunrise."
},
"lat": 27.1751,
"lon": 78.0421
},
{
"id": "p14",
"title": "Kerala Backwaters",
"image": {
"src": "kerala-backwaters.jpg",
"alt": "Tranquil waters and lush greenery of the Kerala backwaters."
},
"lat": 9.4981,
"lon": 76.3388
},
{
"id": "p15",
"title": "African Savanna",
"image": {
"src": "african-savanna.jpg",
"alt": "Wild animals roaming freely in the vast landscapes of the African savanna."
},
"lat": -2.153,
"lon": 34.6857
},
{
"id": "p16",
"title": "Victoria Falls",
"image": {
"src": "victoria-falls.jpg",
"alt": "The powerful cascade of Victoria Falls, a natural wonder between Zambia and Zimbabwe."
},
"lat": -17.9243,
"lon": 25.8572
},
{
"id": "p17",
"title": "Machu Picchu",
"image": {
"src": "machu-picchu.jpg",
"alt": "The historic Incan citadel of Machu Picchu illuminated by the morning sun."
},
"lat": -13.1631,
"lon": -72.545
},
{
"id": "p18",
"title": "Amazon River",
"image": {
"src": "amazon-river.jpg",
"alt": "Navigating the waters of the Amazon River, surrounded by dense rainforest."
},
"lat": -3.4653,
"lon": -58.38
}
]
사용할 places 데이터이다
우선 fetch를 이용해 places 데이터를 가져오쟈 endPoint는 places다
import { useEffect, useState } from "react";
import Places from "./Places.jsx";
export default function AvailablePlaces({ onSelectPlace }) {
const [availablePlaces, setAvailablePlaces] = useState([]);
fetch("http://localhost:5000/places")
.then((response) => {
return response.json();
})
.then((resData) => {
setAvailablePlaces(resData.places);
});
return (
<Places
title='Available Places'
places={availablePlaces}
fallbackText='No places available.'
onSelectPlace={onSelectPlace}
/>
);
}
이렇게 데이터를 가져오게 되면 작동하지 않는다 무한 루프에 빠지기 때문이다 React에서 데이터를 가져올때는 useEffect를 사용해야 한다
import { useEffect, useState } from "react";
import Places from "./Places.jsx";
export default function AvailablePlaces({ onSelectPlace }) {
const [availablePlaces, setAvailablePlaces] = useState([]);
useEffect(() => {
fetch("http://localhost:5000/places")
.then((response) => {
return response.json();
})
.then((resData) => {
setAvailablePlaces(resData.places);
});
}, []);
return (
<Places
title='Available Places'
places={availablePlaces}
fallbackText='No places available.'
onSelectPlace={onSelectPlace}
/>
);
}
useEffect 안에 fetch 코드를 작성하면 데이터가 불러와진다