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 코드를 작성하면 데이터가 불러와진다