[TIL] Axios

ํ˜ฑยท2023๋…„ 11์›” 29์ผ
1

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
44/85
post-thumbnail

Axios ๋ž€?

๐Ÿ‘‰ node.js์™€ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์œ„ํ•œ Proisme ๊ธฐ๋ฐ˜ http ํด๋ผ์ด์–ธํŠธ
์ฆ‰, http๋ฅผ ์ด์šฉํ•ด์„œ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ํŒจํ‚ค์ง€
๐Ÿ“Œ API ์„œ๋ฒ„๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  json-server๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
ํ•œ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ 4000 ๋ฒˆ ํฌํŠธ๋กœ ์„œ๋ฒ„๋ฅผ ๊ฐ€๋™์‹œ์ผœ ์‚ฌ์šฉํ•œ๋‹ค.

์„ค์น˜

yarn add axios

GET

get์€ ์„œ๋ฒ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

// url์—๋Š” ์„œ๋ฒ„์˜ url์ด ๋“ค์–ด๊ฐ€๊ณ , config์—๋Š” ๊ธฐํƒ€ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์„ค์ •์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

axios.get(url[, config]) // GET

axios๋Š” get ์š”์ฒญ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ํŒจํ‚ค์ง€์ผ ๋ฟ์ด์ง€, ์–ด๋–ป๊ฒŒ ์š”์ฒญํ•ด์•ผํ•˜์ง€? ์™€ ๊ฐ™์€ ๋ฐฉ๋ฒ•์€ ์šฐ๋ฆฌ๊ฐ€ ์‚ฌ์šฉํ•  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

post๋Š” ๋ณดํ†ต ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.
๋ณดํ†ต์€ ํด๋ผ์ด์–ธํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ body ํ˜•ํƒœ๋กœ ์„œ๋ฒ„์— ๋ณด๋‚ด๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

axios.post(url[, data[, config]])   // POST

์˜ˆ์‹œ

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

DELETE

delete๋Š” ์ €์žฅ๋˜์–ด ์žˆ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์‚ญ์ œํ•˜๊ณ ์ž ์š”์ฒญํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

axios.delete(url[, config])  // DELETE

์˜ˆ์‹œ

  const onClickDeleteButtonHandler = (todoId) => {
    axios.delete(`http://localhost:3001/todos/${todoId}`);
    setTodos(todos.filter((item) => item.id !== id));
  };

PATCH

patch๋Š” ๋ณดํ†ต ์–ด๋–ค ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๊ณ ์ž ์„œ๋ฒ„์— ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

axios.patch(url[, data[, config]])  // PATCH

์˜ˆ์‹œ

 const onUpdateButtonClickHandler = async () => {
    await api.patch(`http://localhost:3001/todos/${targetId}`, {
      title: content,
    });
    setTodos(
      todos.map((item) => {
        if (item.id == targetId) return { ...item, title: content };
        else return item;
      })
    );
  };

fetch

fetch๋Š” ES6 ๋ถ€ํ„ฐ ๋„์ž…๋œ Javasciprt ๋‚ด์žฅ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๋‹ค. (Promise ๊ธฐ๋ฐ˜ ๋น„๋™๊ธฐ ํ†ต์‹  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)
๋‚ด์žฅ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„์˜ ์„ค์น˜ ๋ฐ import ๊ฐ€ ํ•„์š” ์—†๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์šฐ๋ฆฌ๋Š” fetch ๊ฐ€ ๊ฐ€์ง„ ๋‹จ์ ๋“ค ๋•Œ๋ฌธ์— axios๋ฅผ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

[fetch์˜ ๋‹จ์ ]
1. ๋ฏธ์ง€์› ๋ธŒ๋ผ์šฐ์ € ์กด์žฌ
2. ๊ฐœ๋ฐœ์ž์—๊ฒŒ ๋ถˆ์นœ์ ˆํ•œ response
3. axios์— ๋น„ํ•ด ๋ถ€์กฑํ•œ ๊ธฐ๋Šฅ

CASE 1. ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ

fetch

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

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

fetch().then ์„ ํ•œ ์ƒํƒœ์—ฌ๋„ ์—ฌ์ „ํžˆ JSON ํ˜•์‹์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— response.json()์„ ํ•œ๋ฒˆ ๋” ํ•ด์ฃผ๋Š” ๊ณผ์ •์ด ํ•„์š”ํ•˜๋‹ค.
๊ทธ๋Ÿฌ๋ฏ€๋กœ fetch๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ ๋‘ ๊ฐœ์˜ then ์ด ํ•„์š”ํ•˜๋‹ค.

axios

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

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

axios๋Š” ์นœ์ ˆํ•˜๊ฒŒ๋„ ์‘๋‹ต(response)๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ JSON ํฌ๋งท์œผ๋กœ ์ œ๊ณตํ•œ๋‹ค.
์šฐ๋ฆฌ๋Š” ๋‹จ์ˆœํžˆ response.data๋กœ๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

CASE 2. ์—๋Ÿฌ ์ฒ˜๋ฆฌ

fetch

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);
  });

fetch๋Š” catch๊ฐ€ ์‚ดํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์˜ค์ง ๋„คํŠธ์›Œํฌ ์žฅ์•  ์ผ€์ด์Šค์ด๋‹ค.
๋”ฐ๋ผ์„œ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ผ์ผ์ด then() ์•ˆ์— ๋ชจ๋“  ์ผ€์ด์Šค์— ๋Œ€ํ•œ HTTP ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์•ผ ํ•œ๋‹ค.

axios

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

axios
  .get(url)
  .then((response) => console.log(response.data))
  .catch((err) => {
    console.log(err.message);
  });

axios.get() ์š”์ฒญ์ด ๋ฐ˜ํ™˜ํ•˜๋Š” Promise ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ์ƒํƒœ์ฝ”๋“œ๊ฐ€ 2XX ๋ฅผ ๋„˜์–ด๊ฐ€๋ฉด ๊ฑฐ๋ถ€ (reject)๋ฅผ ํ•œ๋‹ค.
๋”ฐ๋ผ์„œ ๊ณง๋ฐ”๋กœ catch() ๋ถ€๋ถ„์„ ํ†ตํ•ด error handling์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

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

// axios ์š”์ฒญ ๋กœ์ง
axios
  .get(url)
  .then((response) => console.log(response.data))
	.catch((err) => {

		// ์˜ค๋ฅ˜ ๊ฐ์ฒด ๋‚ด์˜ response๊ฐ€ ์กด์žฌํ•œ๋‹ค = ์„œ๋ฒ„๊ฐ€ ์˜ค๋ฅ˜ ์‘๋‹ต์„ ์ฃผ์—ˆ๋‹ค	
		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);
	  }
	});
profile
๋Š๋ฆฌ๋”๋ผ๋„ ์กฐ๊ธˆ์”ฉ, ๊พธ์ค€ํžˆ

0๊ฐœ์˜ ๋Œ“๊ธ€