Script
Axios 본문
Axios
Axios란?
공식문서에 따르면 axios란 node.js와 브라우저를 위한 Promise 기반 http 클라이언트 라고 소개하고 있다.
다시말해, http를 이용해서 서버와 통신하기 위해 사용하는 패키지라고 생각하면 되겠다.
Axios 설치
yarn add axios
Axios를 사용하기 위해 지난에 배운 json-server를 가동시켜 주자.
예시를 위해 아래와 같이 설정해주었다.
{
"todos": [
{
"id": "1",
"title": "react"
}
]
}
GET
Axios get
get은 서버의 데이터를 조회할 때 사용한다. 기본적인 사용법은 아래와 같다.
// url에는 서버의 url이 들어가고, config에는 기타 여러가지 설정을 추가할 수 있다.
// config는 axios 공식문서에서 확인하자.
axios.get(url[, config]) // GET
우리가 사용하는 json-sercer API 명세서 확인하기
우리가 Axios를 사용해서 GET 요청코드를 작성하기에 앞서, 어떤 방식으로 요청 해야할지는 우리가 사용하는
json-server의 방식을 알아보아야 한다.
즉, Axois는 GET 요청을 할 수 있도록 도와주는 패키지일뿐, "어떻게 요청을해야하는가"에 대한 확인은
우리가 사용할 API 명세서를 보아야 한다는 뜻이다.
예를들어 GET 요청을 할 때 path variable로 해야할지, query로 보내야할지는 API를 만든 사람이 하라는대로
해야 하기 때문이다.
json-server의 공식문서를 보면, 전체 정보나 상세 정보는 아래와 같이 path variable로 url을 작성하라고 명시되어
있다.

그리고 filter와 같은 기능을 위해서 GET 요청을 할때는 query로 보내라고 명시되어 있다.

코드로 알아보기
우리가 만든 json-server에 있는 todos를 axios를 이용해서 fetching하고,
useState를 통해서 관리하는 로직이다.
// 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:3001/todos");
setTodos(data); // 서버로부터 fetching한 데이터를 useState의 state로 set 합니다.
};
// 생성한 함수를 컴포넌트가 mount 됐을 떄 실행하기 위해 useEffect를 사용합니다.
useEffect(() => {
// effect 구문에 생성한 함수를 넣어 실행합니다.
fetchTodos();
}, []);
// data fetching이 정상적으로 되었는지 콘솔을 통해 확인합니다.
console.log(todos); // App.js:16
return <div>App</div>;
};
export default App;
결과는 아래와 같다.

POST
Axios POST
axios.post(url[, data[, config]]) // POST
post는 보통 서버에 데이터를 추가할 때 사용한다.
다만, post 요청에 대한 로직은 BE 개발자가 구현하는 것이기 때문에 추가외에 다른 용도로 사용될 수 있지만,
보통은 클라이언트 데이터를 body 형태로 서버에 보내고자 할 때 사용한다.
코드로 알아보기
GET 코드 예시에서 POST 코드를 추가한 것이다.
인풋에 어떤 값을 넣고 버튼을 클릭하면 onSubmitHandler가 실행되고,
이 함수의 목적은 todo를 body에 담아 서버로 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:3001/todos");
setTodos(data);
};
const onSubmitHandler = (todo) => {
axios.post("http://localhost:3001/todos", 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;
네트워크탭 확인하기
네트워크 쪽 개발을 할 때는 항상 브라우저에 있는 네트워크 탭을 확인하면서 개발을 진행해야 한다.
어떤 문제가 생겼을 때 어떤 문제가 생겼을 때 이 정보를 통해 디버깅을 할 수 있기 때문이다.
headers

- Request URL을 통해서 우리가 의도한 URL로 post 요청을 보냈음을 알 수 있다.
- Request Method를 통해서 우리가 POST 메서드를 사용했음을 알 수 있다.
- Status Code를 통해서 201 코드를 받았고, 정상적으로 네트워트가 이루어졌음을 알 수 있다. status code는 자동으로 생성되는 것이 아니라 BE개발자가 직접 개발을 하고 설정한 code가 브라우저에게 보이게 된다. 그래서 만약 BE 개발자가 구현을 해놓지 않았다면 문맥과 다른 status code가 브라우저에 보일 수 있다.
- 그 밖에도 request headers와 reponse headers 정보가 추가적으로 있다.
payload

- payload에서는 우리가 보낸 body를 확인할 수 있다.
response

- reponse에서는 우리가 보낸 post에 요청에 대한 서버의 응답값을 확인할 수 있다. Response 값은 자동으로 생성되는 것이 아니라, FE개발자가 BE 개발자에게 요청한 것을 직접 개발을 해야 생기는 값이다. 우리가 사용한 json-server의 경우 POST 요청 시, 클라이언트가 보낸 body를 그대로 응답해주도록 만들어진 패키지이기 때문에 위와 같이 표시된다.
DELETE
Axios delete
DELETE는 저장되어 있는 데이터를 삭제하고자 요청을 보낼 때 사용한다.
axios.delete(url[, config]) // DELETE
코드로 알아보기
GET, POST와 함께 코드가 작성된다.
onClickDeleteButton 과 map을 돌린 항목별로 삭제하기 버튼을 추가해준다.
// 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:3001/todos");
setTodos(data);
};
const onSubmitHandler = (todo) => {
axios.post("http://localhost:3001/todos", todo);
};
// 새롭게 추가한 삭제 버튼 이벤트 핸들러
const onClickDeleteButtonHandler = (todoId) => {
axios.delete(`http://localhost:3001/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;
DELETE 요청이 성공적으로 이루어졌다면, 브라우저를 새로고침 했을 때 삭제한 Todo가 화면에서 보이지 않는 것을 알 수 있다.
PATCH
Axios patch
patch는 보통 어떤 데이터를 수정하고자 서버에 요청을 보낼 때 사용하는 메서드이다.
다만, 이것은 http 환경에서 서로가 한 약속이자 문맥이기 때문에 수정을 하고자 반드시 patch,put을 써야만
하는 것은 아니다. BE에 의해서 POST를 통해서 "수정"이라는 기능은 충분히 만들 수 있기 때문이다.
다만, 이러한 약속들을 대부분의 개발자들이 지키고 있다는 점을 기억하자.
axios.patch(url[, data[, config]]) // PATCH
코드로 알아보기
put은 patch와 동일한 원리이기 때문에 생략한다.
Todo를 수정하기 위해 필요한 데이터는 2개가 있다. 수정하고자하는 Todo의 id, 그리고 수정하고자 하는 값이다.
수정하고자 하는 값은 기존에 있던 todo라는 state를 사용하면 될 것이고, id는 직접 입력을 해서 url로 넘겨주는 방식으로 구현했다.
보통 수정기능을 만들 때 직접 id를 입력받아 처리하는 방식은 거의 없지만, 예시를 위해 지금과 같이 처리한다는 점을 기억하자.
// 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:3001/todos");
setTodos(data);
};
const onSubmitHandler = (todo) => {
axios.post("http://localhost:3001/todos", todo);
};
const onClickDeleteButtonHandler = (todoId) => {
axios.delete(`http://localhost:3001/todos/${todoId}`);
};
// 수정버튼 이벤트 핸들러 추가 👇
const onClickEditButtonHandler = (todoId, edit) => {
axios.patch(`http://localhost:3001/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;
.env
env란?
env는 API key, port, DB 등 민감한 정보를 환경변수에 담아 관리하는 방법이다.
env 주의사항
1. root 폴더에 생성해야 한다.
root 폴더에 env 파일이 위치하지 않으면 정상적으로 작동하지 않는다.

2. 변수명은 반드시 'REACT_APP_'으로 시작해야 한다.

REACT_APP_변수명 형식이 아닐시, React가 인식하지 못하여 정상적으로 작동하지 않는다.
"process.env.REACT_APP은 예약어다."
3. .gitignore에 env를 등록해야 한다.

.gitignore에 등록해주어야 git에 등록할 때, 파일이 올라가지 않는다.
(기본으로 세팅이 되어있지만 확인해주도록 하자.)
env 사용방법
1. root 폴더에 env 파일 생성

먼저 root 폴더 (package 파일과 같은 레벨)에 env 파일을 생성해준다.
2. 환경변수 입력

key,value 형식으로 환경변수를 입력해준다.
주의해야 할점은 key 앞에는 무조건 'REACT_APP_'을 붙여야 한다.
3.환경변수 불러오기

소스코드에서 import 없이 process.env.REACT_APP_변수명으로 불러오면 적용된다.
(만약 env의 값을 변경하여 적용하고 싶다면, 변경 후 server를 다시 실행시켜 주어야 정상적으로 적용된다.)
결과화면에는 A가 출력되는 것을 볼 수 있다.
출처:https://tooo1.tistory.com/582
정리
- Axios를 이용해서 API 서버와 통신할 수 있다.
- Axios는 http 통신을 도와주는 패키지이며, 구체적인 명세서는 API 명세서를 확인해야 한다.
- 브라우저 네트워크 탭을 잘 봐야한다.
- http method,status code와 같은 정보들은 BE 개발자가 구현해주는 부분이며, 약속이자 문맥이므로 BE와 FE간의 커뮤니케이션이 잘 되어야 한다
'항해99 > 5주차 주특기 심화' 카테고리의 다른 글
| Custom Hook (0) | 2022.08.11 |
|---|---|
| Thunk 2 (0) | 2022.08.11 |
| Thunk (0) | 2022.08.10 |
| json-server (0) | 2022.08.08 |
| Redux Toolkit (0) | 2022.08.07 |