본문 바로가기
Javascript, Typescript, React

TIL 13주 day2 - React에서 경로 이동, HTTP 통신 시 fetch, axios

by 케이리케리 2024. 2. 15.

📍경로로 이동하는 방법(Link, useNavigate)

Link

  • Link 는 특정 주소로 이동해주는 태그
  • Link 컴포넌트는 React에서 사용하는 <a> 태그라고 생각하면된다.
  • <a> 태그의 경우, href로 지정한 주소로 이동하기때문에 새로고침이 일어난다. 그래서 애플리케이션이 들고 있던 상태들을 모두 날려 버리게 되며 다시 처음부터 렌더링을 한다
  • <Link>의 경우, 페이지를 새로 불러오지 않고 애플리케이션은 그대로 유지한 상태에서 HTML5 History API를 사용하여 페이지의 주소만 변경해 준다.
  • <a> 태그는 href를 통해 , <Link>는 to를 통해 이동한다.
import { Link } from 'react-router-dom';

function MyComponent() {
	return (
		<Link to="/about">About</Link>
	);
}

useNavigate

  • useNavigate는 함수형 컴포넌트에서 사용하는 훅들 중 하나이다.
  • 옵션으로 replace,state 설정 가능하다. (replace: 이동하면서 접근 이력 유지 여부 선택, state: 이동과 함께 전달하려는 값)
  • 함수 호출을 통해 페이지를 이동한다는 것이 특징 (특정 조건을 충족하거나, 특정 행동 시 페이지 이동하도록 설정)
  • 페이지 이동 시 추가적인 로직이 필요한 경우에 사용한다.
import React from "react";
import { useNavigate } from "react-router-dom";

function Login() {
  const navigate = useNavigate();

const goToMain = () => {
	if(response.message === "valid user"){
	   navigate('/main');   
	} else {
	   alert("가입된 회원이 아닙니다. 회원가입을 먼저 해주세요.")
	   navigate('/signup');
	}
}

  return (
    <div>
      <button className="loginBtn" onClick={goToMain}>
        로그인
      </button>
    </div>
  );
}

export default Login;
  • Link와 다른 점은 함수 호출을 통해 페이지를 이동하기 때문에 위와 같이 특정 조건을 충족할 경우에 페이지 이동을 하도록 할 수 있다.

📍Fetch와 Axios 사용 비교

Fetch

  • Fetch API는 네트워크 요청을 위해 fetch()라는 메서드를 제공하는 인터페이스이다.
  • Javascript에 내장된 API
  • 모던 브라우저에 내장되어 있어 따로 설치할 필요가 없다.

Axios

  • 서드파티 라이브러리로 CDN 혹은 npm 이나 yarn과 같은 패키지 매니저를 통해 설치해야한다.
  • 브라우저 혹은 node.js 환경에서 실행할 수 있습니다.
  • 크로스 브라우징 기반으로 브라우저 호환성이 뛰어나다.

둘다 promise 기반의 HTTP 클라이언트이다. 즉, 이 클라이언트를 이용해 네트워크 요청을 하면 이행(resolve) 혹은 거부(reject)할 수 있는 promise가 반환된다.


문법

Fetch

두 개의 인자를 받는다. 첫 번째 인자는 가져오고자 하는 리소스의 URL, 두 번째 인자는 요청의 설정 옵션을 포함하는 객체로 선택적 인자이다.

두 번째 인자로 설정 옵션을 넘기지 않으면, 기본적으로 GET 요청 생성

fetch(url, {
  method: "GET", // 다른 옵션도 가능합니다 (POST, PUT, DELETE, etc.)
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
});

Axios

HTTP 메서드 붙이는 방법

axios.get(url, {
  // 설정 옵션
});

HTTP 메서드 붙이지 않는 방법

axios(url, {
  method: "get", // 다른 옵션도 가능합니다 (post, put, delete, etc.)
  headers: {},
  data: {},
});

url을 객체 안에 작성할 수 도 있음

axios({
  method: "get",
  url: url,
  headers: {},
  data: {},
});

JSON 데이터 처리

Fetch

const url = "<https://jsonplaceholder.typicode.com/todos>";

fetch(url)
  .then((response) => response.json())
  .then(console.log);

데이터를 사용하기 위해서는 .json() 메서드를 호출해서 JSON 형식 데이터로 변환 과정이 필요하다.

그래서 일반적인 fetch 요청은 두 개의 .then() 호출을 갖는다.

Axios

const url = "<https://jsonplaceholder.typicode.com/todos>";

axios.get(url).then((response) => console.log(response.data));

Axios를 사용하면 응답 데이터를 기본적으로 JSON 타입으로 사용할 수 있다. 응답 데이터는 언제나 응답 객체의 data 프로퍼티에서 사용할 수 있다.


자동 문자열 변환(stringify)

데이터 전송을 위해 데이터를 JSON 문자열로 직렬화해야 한다.

Axios

POST 메서드로 JavaScript 객체를 API로 전송하면 Axios가 자동으로 데이터를 문자열로 변환해준다.

const url = "<https://jsonplaceholder.typicode.com/todos>";

const todo = {
  title: "A new todo",
  completed: false,
};

axios
  .post(url, {
    headers: {
      "Content-Type": "application/json",
    },
    data: todo,
  })
  .then(console.log);

Axios로 post요청을 할 때 요청 본문(request body)으로 보내고자 하는 data는 data 프로퍼티에 할당한다.

컨텐츠 유형 헤더도 설정할 수 있는데 기본적으로 axios는 Content-Type을 application/json으로 설정한다.

Fetch

Fetch API를 사용한다면 JSON.stringify()를 사용하여 객체를 문자열으로 변환한 뒤 body에 할당해야 한다.

명시적으로 Content-Type을 application/json으로 설정해야 한다.

const url = "<https://jsonplaceholder.typicode.com/todos>";

const todo = {
  title: "A new todo",
  completed: false,
};

fetch(url, {
  method: "post",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(todo),
})
  .then((response) => response.json())
  .then((data) => console.log(data));

에러 처리

Fetch와 axios는 모두 이행(resolve) 되거나 거부(reject)된 promise를 반환한다.

Promise가 거부(reject)되면 .catch()를 사용하여 에러를 처리할 수 있다.

Axios로 에러를 처리하는 방법은 Fetch에 비해 더 간결함

Axios

const url = "<https://jsonplaceholder.typicode.com/todos>";

axios
  .get(url)
  .then((response) => console.log(response.data))
  .catch((err) => {
	  // 에러 처리
		if (err.response) {
		// 요청이 이루어졌고 서버가 응답했을 경우
		
	    const { status, config } = err.response;
	
	    if (status === 404) {
	      console.log(`${config.url} not found`);
	    }
	    if (status === 500) {
	      console.log("Server error");
	    }
	
	  } else if (err.request) {
	    // 요청이 이루어졌으나 서버에서 응답이 없었을 경우
	    console.log("Error", err.message);
	  } else {
	    // 그 외 다른 에러, 요청 또는 응답 속성이 모두 없는 경우는 네트워크 요청을 설정하는 동안 오류가 발생한 경우
	    console.log("Error", err.message);
	  }
	});

Axios의 promise는 **상태코드가 2xx의 범위를 넘어가면 거부(reject)**한다.

에러 객체에 응답(response) 또는 요청(request) 프로퍼티가 포함되어 있는지 확인하여 에러에 대한 자세한 정보를 확인할 수 있다.

Fetch

Fetch는 404 에러나 다른 HTTP 에러 응답을 받았다고 해서 promise를 거부(reject)하지 않는다.

네트워크 장애가 발생한 경우에만 promise를 거부(reject) 한다.

따라서 .then절을 사용해 수동으로 HTTP 에러를 처리해야 합니다.

const url = "<https://jsonplaceholder.typicode.com/todos>";

fetch(url)
  .then((response) => {
    if (!response.ok) {
      throw new Error(
        `This is an HTTP error: The status is ${response.status}`
      );
    }
    return response.json();
  })
  .then(console.log)
  .catch((err) => {
    console.log(err.message);
  });

응답 블록에서 응답의 ok 상태가 false인 경우 .catch 블록에서 처리되는 커스텀 에러를 발생시킨다.

.then(console.log)

위에는 fetch가 성공했을 때

잘못된 URL 엔드포인드라면? status : 404, ok : false값을 가지게 됨 → .catch()절에서 커스텀 에러 메세지를 출력


응답 시간 초과 / 요청 취소

Axios

timeout 속성을 설정 객체에 추가하여 요청이 종료될 때까지의 시간을 밀리초로 지정할 수 있다.

const url = "<https://jsonplaceholder.typicode.com/todos>";

axios
  .get(url, {
    timeout: 4000, // 기본 설정은 '0'입니다 (타임아웃 없음)
  })
  .then((response) => console.log(response.data))
  .catch((err) => {
    console.log(err.message);
  });

만약 요청이 4초 이상 걸릴 경우에 종료하고 console창에 error를 출력

Fetch

Fetch를 통한 요청을 취소하기 위해서는 AbortController 인터페이스를 사용할 수 있다.

const url = "<https://jsonplaceholder.typicode.com/todos>";

const controller = new AbortController();
const signal = controller.signal;
setTimeout(() => controller.abort(), 4000);

fetch(url, {
  signal: signal,
})
  .then((response) => response.json())
  .then(console.log)
  .catch((err) => {
    console.error(err.message);
  });

controller 객체를 생성하고나서 signal 객체와 abort() 메서드에 접근했고

이 signal객체를 설정 옵션을 통해 fetch()에 넘김.

이렇게 하면 abort 메서드가 호출될 때마다 fetch 요청이 종료됨.

setTimeout 기능을 사용하여 서버가 4초 이내에 응답하지 않으면 작업이 종료된다.

 

 

  • 사용의 용이성: Axios는 오류 처리, JSON 변환 등에서 사용자 친화적이다.
  • 기능성: Axios는 요청 취소, HTTP 상태 코드에 기반한 자동 오류 처리, 인터셉터 등 추가 기능을 제공한다.
  • 간단한 요청만 필요한 경우 Fetch를 사용할 수 있다. 반면, 복잡한 요청, 더 나은 오류 처리, 추가 기능이 필요한 경우 Axios를 선택을 많이 한다,

프로젝트에 어떤 방법을 사용할지는 개인의 선호도나 사용 편의성에 따라 달라질 것이다.