[React ] study(5) Axios

dev kyu·2025년 1월 13일

React

목록 보기
9/11

Axios란,

웹에서 데이터를 가져오거나 서버로 데이터를 보내기 위한 도구야.
쉽게 말해, 웹 브라우저와 서버가 대화할 수 있도록 도와주는 메신저라고 생각하면 돼!

📍핵심 설명

Axios는 배달 앱처럼 동작해!

  • 클라이언트(사용자): "피자를 주문할게요!" 하고 요청을 보냄.

  • Axios(배달 앱): 주문 요청을 가게(서버)로 전달하고, 결과를 받아옴.

  • 서버(가게): 요청을 처리하고, 피자(데이터)를 배달 앱(Axios)에게 전달.

  • 클라이언트(사용자): 배달 앱(Axios)을 통해 데이터를 받아 결과를 확인.


🔍 Axios의 주요 역할

  • 데이터 요청 (GET): 서버에서 데이터를 가져옴.
    (예) 게시글 목록을 가져오기.
  • 데이터 전송 (POST): 서버에 데이터를 보냄.
    (예) 회원가입 정보 전송.
  • 서버와 통신 오류 처리: 요청이 실패하면 에러를 쉽게 처리.

🔍 Axios의 사용 예제

1️⃣ Axios 설치

패키지 매니저설치 명령어
yarnyarn add axios
pnpmpnpm add axios

2️⃣ GET 요청 예제 (서버에서 데이터 가져오기)

import axios from 'axios';

axios.get('https://jsonplaceholder.typicode.com/posts')
  .then((response) => {
    console.log(response.data); // 가져온 데이터를 출력
  })
  .catch((error) => {
    console.error('데이터 가져오기 실패:', error);
  });
// axios.get()은 서버에 데이터를 요청하는 코드야. 요청이 성공하면 response.data로 데이터를 받아오고, 실패하면 catch에서 에러를 처리해.

3️⃣ POST 요청 예제 (서버로 데이터 보내기)

import axios from 'axios';

axios.post('https://jsonplaceholder.typicode.com/posts', {
  title: '새 게시글',
  body: '내용입니다.',
  userId: 1
})
  .then((response) => {
    console.log('성공적으로 추가됨:', response.data);
  })
  .catch((error) => {
    console.error('추가 실패:', error);
  });
//axios.post()는 데이터를 서버로 보내는 코드야, 여기서는 새로운 게시글 정보를 서버로 전송해.

🔍 섬세한 설명

  • axios.get

    get은 서버의 데이터를 조회할 때 사용.
// url에는 서버의 url이 들어가고, config에는 기타 여러가지 설정 추가가능.
// config는 axios 공식문서에서 확인해봐!
axios.get(url[, config]) // GET(url은 매개변수, 대괄호([]) 안의 값은 선택 입력사항.

axios 공식문서

  • 예시코드
// src/App.js

import React, { useEffect, useState } from "react";
import axios from "axios"; // axios import

const App = () => {
  const [todos, setTodos] = useState(null);

	// axios를 통해서 get 요청을 하는 함수를 생성.
	// 비동기처리를 해야하므로 async/await 구문을 통해서 처리.
  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:4000/todos");
    setTodos(data); // 서버로부터 fetching한 데이터를 useState의 state로 set.
  };
	
	// 생성한 함수를 컴포넌트가 mount된 후 실행하기 위해 useEffect를 사용.
  useEffect(() => {
		// effect 구문에 생성한 함수를 넣어 실행.
    fetchTodos();
  }, []);

	// data fetching이 정상적으로 되었는지 콘솔을 통해 확인.
  console.log(todos);
  return <div>App</div>;
};

export default App;
  • axios.post

    post는 보통 서버에 데이터를 추가할 때 사용.
// 보통은 클라이언트의 데이터를 body형태로 서버에 보내고자 할 때 사용.
axios.post(url[, data[, config]])   // POST
  • 예시코드
// src/App.jsx

import React, { useEffect, useState } from "react";
import axios from "axios"; // axios import

const App = () => {
  // 새롭게 생성하는 todo를 관리하는 state
  const [todo, setTodo] = useState({
    title: "",
  });

  const [todos, setTodos] = useState(null);

  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:4000/todos");
    setTodos(data);
  };

	// (원리를 꼭 이해!!!)
	// HTTP에서는 body에 javascript 객체를 direct로 넣을 수 없어!
	// axios는 내부적으로 JSON.stringify를 적용하기 때문에 이처럼 편리하게 사용하는 것 뿐이야.
  const onSubmitHandler = async(todo) => {
    await axios.post("http://localhost:4000/todos", todo);
  };
  
  // 만일 fetch를 사용했다면, 이렇게 JSON.stringify를 '직접' 해줘야 해.
  // await fetch("http://localhost:4000/todos", {
  //   method: "POST",
  //   headers: {
  //     "Content-Type": "application/json",
  //   },
  //   body: JSON.stringify(todo),
  // });

  useEffect(() => {
    fetchTodos();
  }, []);

  return (
    <>
      <form
        onSubmit={(e) => {
					// 👇 submit했을 때 브라우저의 새로고침을 방지. 
          e.preventDefault();
          onSubmitHandler(todo);
        }}
      >
        <input
          type="text"
          onChange={(ev) => {
            const { value } = ev.target;
            setTodo({
              ...todo,
              title: value,
            });
          }}
        />
        <button>추가하기</button>
      </form>
      <div>
        {todos?.map((todo) => (
          <div key={todo.id}>{todo.title}</div>
        ))}
      </div>
    </>
  );
};

export default App;
  • axios.delete

    delete는 저장되어 있는 데이터를 삭제요청 할때 사용.
axios.delete(url[, config])  // delete
  • 예시코드
// src/App.jsx

import React, { useEffect, useState } from "react";
import axios from "axios"; 

const App = () => {
  const [todo, setTodo] = useState({
    title: "",
  });

  const [todos, setTodos] = useState(null);

  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:4000/todos");
    setTodos(data); 
  };

  const onSubmitHandler = (todo) => {
    axios.post("http://localhost:4000/todos", todo);
  };

	// 새롭게 추가한 삭제 버튼 이벤트 핸들러 
  const onClickDeleteButtonHandler = (todoId) => {
    axios.delete(`http://localhost:4000/todos/${todoId}`);
  };

  useEffect(() => {
    fetchTodos();
  }, []);

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          onSubmitHandler(todo);
        }}
      >
        <input
          type="text"
          onChange={(ev) => {
            const { value } = ev.target;
            setTodo({
              ...todo,
              title: value,
            });
          }}
        />
        <button>추가하기</button>
      </form>
      <div>
        {todos?.map((todo) => (
          <div key={todo.id}>
            {todo.title}
            <button
              type="button"
              onClick={() => onClickDeleteButtonHandler(todo.id)}
            >
              삭제하기
            </button>
          </div>
        ))}
      </div>
    </>
  );
};

export default App;
  • axios.patch

    patch는 어떤 데이터를 수정요청 할때 사용.
axios.patch(url[, data[, config]])  // patch
  • 예시코드
// src/App.jsx

import React, { useEffect, useState } from "react";
import axios from "axios";

const App = () => {
  const [todo, setTodo] = useState({
    title: "",
  });
  const [todos, setTodos] = useState(null);

  // patch에서 사용할 id, 수정값의 state를 추가
  const [targetId, setTargetId] = useState(null);
  const [editTodo, setEditTodo] = useState({
    title: "",
  });

  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:4000/todos");
    setTodos(data);
  };

  const onSubmitHandler = (todo) => {
    axios.post("http://localhost:4000/todos", todo);
  };

  const onClickDeleteButtonHandler = (todoId) => {
    axios.delete(`http://localhost:4000/todos/${todoId}`);
  };

  // 수정버튼 이벤트 핸들러 추가 👇
  const onClickEditButtonHandler = (todoId, edit) => {
    axios.patch(`http://localhost:4000/todos/${todoId}`, edit);
  };

  useEffect(() => {
    fetchTodos();
  }, []);

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          onSubmitHandler(todo);
        }}
      >
        {/* 👇 수정기능에 필요한 id, 수정값 input2개와 수정하기 버튼을 추가 */}
        <div>
          <input
            type="text"
            placeholder="수정하고싶은 Todo ID"
            onChange={(ev) => {
              setTargetId(ev.target.value);
            }}
          />
          <input
            type="text"
            placeholder="수정값 입력"
            onChange={(ev) => {
              setEditTodo({
                ...editTodo,
                title: ev.target.value,
              });
            }}
          />
          <button
						// type='button' 을 추가해야 form의 영향에서 벗어남
            type="button"
            onClick={() => onClickEditButtonHandler(targetId, editTodo)}
          >
            수정하기
          </button>
        </div>
        <input
          type="text"
          onChange={(ev) => {
            const { value } = ev.target;
            setTodo({
              ...todo,
              title: value,
            });
          }}
        />
        <button>추가하기</button>
      </form>
      <div>
        {todos?.map((todo) => (
          <div key={todo.id}>
						{/* todo의 아이디를 화면에 표시 */}
            {todo.id} :{todo.title}
            <button
              type="button"
              onClick={() => onClickDeleteButtonHandler(todo.id)}
            >
              삭제하기
            </button>
          </div>
        ))}
      </div>
    </>
  );
};

export default App;

🙌 네트워크 쪽 개발을 할 때는 항상 브라우저에 있는 네트워크 탭을 확인하면서 개발을 진행해야 해, 어떤 문제가 생겼을 때 이정보를 통해 디버깅을 할 수 있기 때문이야.


🚀 진짜 쉬운 설명

Axios는 웹에서 데이터를 주고받는 작업을 간단하고 효율적으로 처리할 수 있도록 도와주는 도구야. "서버와 대화할 때 쓰는 편리한 메신저"로 생각하면 쉽다!


✏️ 더 알아가기

  • axios와 fetch 차이점
항목AxiosFetch
사용 편의성간단한 문법과 추가 기능 제공기본적으로 약간의 추가 코드 필요
JSON 자동 처리요청 및 응답에서 JSON 자동 처리JSON 변환을 수동으로 처리해야 함
요청 취소 기능기본적으로 요청 취소 기능 제공추가 라이브러리(AbortController) 필요
오류 처리HTTP 오류를 자동으로 .catch에서 처리HTTP 오류를 직접 확인 후 처리 필요
브라우저 지원모든 브라우저에서 동작최신 브라우저만 지원 (구형 브라우저 제한)
추가 기능타임아웃 설정, 헤더 관리 등 추가 기능 제공기본 기능만 제공
  • json-server API 명세서 확인방법

Axios를 사용해서 GET 요청 코드를 작성하기에 앞서, 어떤 방식으로 요청 해야할지는 우리가 사용하는 json-server의 방식을 알아봐야 해.

다시 말해, Axios는 GET 요청을 할 수 있도록 도와주는 패키지일뿐이지, “어떻게 요청을 해야하지?” 와 같은 방식에 대한 확인은 우리가 사용할 API 명세서를 보아야 한다는 뜻이야. 예를 들어 GET 요청을 할 때 path variable로 해야할지, query로 보내야할지는 API를 만든 사람이 하라는대로 해야 하기때문이지.

  • .env와 .gitignore란?

    .env(환경 변수 파일)
    .env 파일은 중요한 설정 값이나 비밀 정보를 저장하는 파일이야.
    (예) API 키, 데이터베이스 비밀번호, 서버 URL 등.
    코드에 직접 노출하지 않고, 안전하게 관리하기 위해 사용해.

  • .env 사용법

  1. 프로젝트에 .env 파일 생성: 파일 이름: .env
  2. 환경 변수 저장: 키=값 형태로 작성.
API_KEY=123456789
DATABASE_URL=https://example.com
SECRET_KEY=mysecret
  1. 코드에서 불러오기.
require('dotenv').config();

console.log(process.env.API_KEY); // "123456789"

.gitignore(Git 제외 파일 설정)
.gitignore 파일은 Git에 포함시키지 않을 파일이나 폴더를 지정하는 파일야.
(예) node_modules, .env, 빌드 파일 등.
민감한 정보나 불필요한 파일이 저장소에 올라가지 않도록 방지해.

  • .gitignore 사용법
  1. 프로젝트에 .gitignore 파일 생성: 파일 이름: .gitignore
  2. Git에 포함하지 않을 파일 추가: 무시할 파일이나 폴더를 작성.
# node_modules 폴더 제외
node_modules/

# 환경 변수 파일 제외
.env

# 로그 파일 제외
*.log

# 운영 시스템별 파일 제외 (예: macOS)
.DS_Store
  1. 확인하기.
    .gitignore에 추가된 파일은 Git 상태에 나타나지 않아.
    이미 커밋된 파일은 제외되지 않으므로, 이를 삭제하려면 아래 명령어를 사용해야해.
git rm --cached 파일이름
  • .env가 중요한 이유:
    • 보안: 중요한 정보를 코드에 직접 노출하지 않음.
    • 환경별 설정 관리: 로컬 개발, 스테이징, 프로덕션 환경별로 다른 설정을 쉽게 관리.
  • .gitignore가 중요한 이유:
    • 저장소 정리: 프로젝트와 관련 없는 파일을 Git에 올리지 않아, 저장소가 깔끔해.
    • 보안: 민감한 정보(.env 파일 등)가 저장소에 올라가지 않도록 방지.
  • 한줄요약
    • .env 민감한 정보(예: API 키, 비밀번호)를 안전하게 저장.
    • .gitignore Git에 올리지 않을 파일을 지정해 저장소를 깨끗하고 안전하게 관리.
profile
dev kyu

0개의 댓글