JiSoo's Devlog

[Udemy React 완벽 가이드] HTTP 요청 보내기 본문

Frontend/React

[Udemy React 완벽 가이드] HTTP 요청 보내기

지숭숭숭 2024. 5. 30. 21:18

프론트엔드와 백엔드를 연결하기 위해서는 HTTP 요청을 사용해야 한다

그래야 리액트 앱 내에서 HTTP 요청을 백엔드로 보내 데이터를 요청하거나 바꾸도록 요청할 수 있다

 

데이터베이스와 소통해야 한다면 우리는 리액트로 클라이언트 쪽 코드를 쓰는 것

Endpoint라고 불리는 백엔드 API를 사용하면 되는데 이건 특정 요청만 받는 URL

 

API는 두 시스템이 상호작용할 수 있게 하는 프로토콜의 총집합

Endpoint는 API가 서버에서 리소스에 접근할 수 있도록 가능하게 하는 URL, 즉 요청을 받아 응답을 제공하는 서비스를 사용할 수 있는 지점을 의미한다

 

절대 데이터베이스와 내부 리액트 코드를 직접적으로 연결하려 하면 안 된다

그러면 데이터베이스 인증 정보가 노출된다

 

백엔드는 어떤 종류의 요청을 허락하고 어떤 요청들을 차단할지 통제한다

 

localStorage에서 데이터를 가져오기 위해 getItem 메소드를 사용하는 경우도 있다

로컬 저장소의 큰 장점은 실시간으로 접속할 수 있다는 것이고 가져오려는 데이터가 즉각 준비되어 있다는 것이다

 

내장 fetch함수는 리액트가 제공하는 게 아니라 브라우저가 직접 제공하는 것이다

HTTP 요청을 다른 서버들로 보내는 데 사용한다

기본적으로 fetch가 원하는 건 요청을 보내려는 서버의 URL

 

fetch는 Promise를 반환하는데 Promise는 표준 자바스크립트 객체로 해당 state에 따라 각 다른 값을 산출한다

그 값들에 접근하려면 fetch로 불러온 결과로 메소드들을 한데 묶을 수 있다

then 메소드를 추가할 수 있고 그 메소드에 함수를 전달해 함수를 정의하면 이 Promise가 해결되고 Response를 받고 나서 한 번 실행된다

 

최신 자바스크립트는 await 키워드를 사용해 이 Response들에 접근할 수 있다

하지만 이게 가능한 건 오직 이 함수에서 코드가 비동기(async)로 실행될 때인데 컴포넌트 함수들에게는 허용되지 않는다

 

 fetch("http://localhost:3000/places").then((response)=>{
    return response.json()
  })

json 메소드는 JSON 형식의 데이터를 추출하는데 사용할 수 있다

JSON은 간단하게 텍스트 기반 데이터 형식이며 자바스크립트 배열과 객체와 비슷하다고 볼 수 있다

JSON 메소드는 또 다른 프로미스를 반환하기 때문에 또 다른 then 메소드를 추가할 수 있다

fetch("http://localhost:3000/places")
    .then((response) => {
      return response.json();
    })
    .then((resData) => {
      setAvailablePlaces(resData.places);
    });

하지만 이렇게 하면 무한 루프를 생성하게 되는 문제가 생긴다

useEffect로 해결하기

Effect 함수는 의존성이 바뀌었다는 전제 하에 항상 컴포넌트 함수가 실행된 직후 즉시 실행된다

useEffect(() => {
    fetch("http://localhost:3000/places")
      .then((response) => {
        return response.json();
      })
      .then((resData) => {
        setAvailablePlaces(resData.places);
      });
  }, []);

 

async await를 사용하기 위해 Effect 함수에서 새로운 함수 생성

useEffect(() => {
    async function fetchPlaces() {
      const response = await fetch("http://localhost:3000/places");
      const resData = await response.json();
      setAvailablePlaces(resData.places);
    }
    fetchPlaces();
  }, []);

비동기로 정의하고 즉시 불러내기

 

HTTP 요청을 보낼 때 대부분 state와 도착할 데이터만 관리하지 않고 loading state도 함께 관리해야 한다

const [isFetching, setIsFetching] = useState(false);
  useEffect(() => {
    async function fetchPlaces() {
      setIsFetching(true);
      const response = await fetch("http://localhost:3000/places");
      const resData = await response.json();
      setAvailablePlaces(resData.places);
      setIsFetching(false);
    }
    fetchPlaces();
  }, []);

 

 

HTTP 요청을 보낼 때 에러 발생

데이터 fetching에 실패할 수 있다는 걸 항상 염두에 둬야 한다

실패하는 큰 이유 두 가지

1. 요청을 보내는 것에 실패하는 것

2. 요청을 보낼 때 백엔드에서는 성공적으로 전달되었지만 거기서부터 문제가 발생해 에러 응답을 보내는 경우

 

fetch 함수를 사용해 HTTP 요청을 보낼 때 응답이 에러 응답인지 확인할 수 있다

response.ok 속성을 확인하면 되는데 true면 200-300 정도의 상태 코드는 받고

false라면 400이나 500 정도의 상태 코드를 받는다

 

데이터를 가져올 때 흔하게 3가지 상태들이 함께 동작한다

const [availablePlaces, setAvailablePlaces] = useState([]);
const [isFetching, setIsFetching] = useState(false);
const [error, setError] = useState();

 

useEffect(() => {
    async function fetchPlaces() {
      setIsFetching(true);

      try {
        const response = await fetch("http://localhost:3000/places");
        const resData = await response.json();

        if (!response.ok) {
          throw new Error("Failed to fetch places");
        }

        setAvailablePlaces(resData.places);
      } catch (error) {
        setError({
          message:
            error.message || "Could not fetch places, please try again later",
        });
      }

      setIsFetching(false);
    }
    fetchPlaces();
  }, []);

 

 

POST 요청으로 데이터 전송하기

fetch로 요청을 보낼 때 두 번째 인수에 나가는 요청들을 설정하는 설정함수가 와야 한다

const response = await fetch("http://localhost:3000/user-places", {
    method: "PUT",
    body: JSON.stringify({ places }),
    headers: {
      "Content-Type": "application/json",
    },
  });

메소드 속성을 설정하고, body 속성을 추가해 어떤 데이터가 요청 body에 첨부되어야 하는지 정의한다

나가는 요청 body에 대한 내용이 꼭 첨부될 수 있는 형식이어야 하는데 자바의 배열은 첨부할 수 있는 형식이 아니라서 JSON 형식으로 변환되어야 한다

요청에 첨부될 추가 메타데이터인 헤더도 추가해야 한다

 

728x90