[React] Axios ์‚ฌ์šฉ ๐Ÿ‘‰ json-server ํ…Œ์ŠคํŠธ

TH_velogยท2023๋…„ 12์›” 8์ผ
1

React

๋ชฉ๋ก ๋ณด๊ธฐ
14/16
post-thumbnail

๐Ÿ“Œ Axios

๐Ÿ“– Axios๋ž€?

  • ์•ก์‹œ์˜ค์Šค(Axios)
  • Promise ๊ธฐ๋ฐ˜ HTTP ๋น„๋™๊ธฐ ํ†ต์‹  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

โœ… ํŠน์ง•

  • Promise API๋ฅผ ์ง€์›
  • ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์œ„ํ•ด XMLHttpRequests ์ƒ์„ฑ
  • node.js๋ฅผ ์œ„ํ•ด http ์š”์ฒญ ์ƒ์„ฑ
  • ์š”์ฒญ, ์ทจ์†Œ, ์‘๋‹ต ์ธํ„ฐ์…‰ํŠธ, ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜,
  • JSON ๋ฐ์ดํ„ฐ ์ž๋™ ๋ณ€ํ™˜
  • XSRF๋ฅผ ๋ง‰๊ธฐ์œ„ํ•œ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ์ง€์›

โš ๏ธ fetch์™€ axios๋ฅผ ์ค‘ axios๋ฅผ ๋งŽ์ด ์‚ฌ์šฉํ•˜์—ฌ axios ํ…Œ์ŠคํŠธ
fetch๋„ ์•Œ์•„๋ณด๊ธฐ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค!


๐Ÿ“— Axios ์„ค์น˜

npm install axios

โœ… package.json ํŒŒ์ผ ํ™•์ธ


๐Ÿ“— Axios ์‚ฌ์šฉ๋ฒ•

import axios from 'axios';

// 1. 
axios.get("URL")
  .then((response) => { // ์„ฑ๊ณต
    console.log(response)
  })
  .catch((error) => { // ์‹คํŒจ
    console.log(error)
  })

// 2.
async function axiosGet(){
 try {
   const response = await axios.get("URL");
   console.log(response)
 } catch(error){
   console.log(error)
 }
}

โœ… ์š”์ฒญ ๋ฉ”์†Œ๋“œ ๋ช…๋ น์–ด
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

โœ… ๋Œ€ํ‘œ์ ์œผ๋กœ ์•„๋ž˜ 4๊ฐ€์ง€๋ฅผ ์‚ฌ์šฉ

// ๊ฐ€์ ธ์˜ค๊ธฐ ์ฝ๊ธฐ
GET : axios.get(url[, config])
// ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
POST : axios.post(url, data[, config])
// ๋ฐ์ดํ„ฐ ์ˆ˜์ •
PUT : axios.put(url, data[, config])
// ๋ฐ์ดํ„ฐ ์‚ญ์ œ
DELETE : axios.delete(url[, config])

๐Ÿ”— Axios ์ฐธ๊ณ 
https://axios-http.com/
https://axios-http.com/kr/docs/intro
Inpa Dev


๐Ÿ“— Axios ํ…Œ์ŠคํŠธ (json-server)

๐Ÿ“˜ test json ํŒŒ์ผ ์ƒ์„ฑ

โœ… ./data/data.json ์ƒ์„ฑ (src์™€ ๋™์ผํ•œ ์œ„์น˜, ํ˜•์ œ ์œ„์น˜)

{
  "test": [
    {
      "id":1,
      "name":"์ด๋ฆ„1",
      "desc":"ํ…Œ์ŠคํŠธ ์ค‘"
    },
    {
      "id":2,
      "name":"์ด๋ฆ„2",
      "desc":"ํ…Œ์ŠคํŠธ ์ค‘"
    },
    {
      "id":3,
      "name":"์ด๋ฆ„3",
      "desc":"ํ…Œ์ŠคํŠธ ์ค‘"
    },
    {
      "id":4,
      "name":"์ด๋ฆ„4",
      "desc":"ํ…Œ์ŠคํŠธ ์ค‘"
    },
    {
      "id":5,
      "name":"์ด๋ฆ„5",
      "desc":"ํ…Œ์ŠคํŠธ ์ค‘"
    }
  ]
}

๐Ÿ“˜ json-server

โœ… Axios๋ฅผ ์—ฐ์Šตํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์งœ API ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค๊ณ  ์‹คํ–‰!!

  • json ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜๊ณ  TEST ํ…Œ์ดํ„ฐ๋ฅผ ๋งŒ๋“ค๊ณ  ๋ถˆ๋Ÿฌ์˜ค๊ณ  ์ˆ˜์ •ํ•˜๊ธฐ

port : React 3000 ์‚ฌ์šฉ / json-server 4000 ์‹คํ–‰.

$ npx json-server ./data/data.json --port 4000

๊ธ€๋กœ๋ฒŒ ์„ค์น˜ ํ›„ json-server ./data.json --port 4000 ์‚ฌ์šฉ ๊ฐ€๋Šฅ

npm install -g json-server

โœ… ์‹คํ–‰ ์™„๋ฃŒ ํ™”๋ฉด
Resources ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ถœ๋ ฅ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ‘

React ์‹คํ–‰ํ•˜๊ณ  json-server ๋”ฐ๋กœ ์‹คํ–‰ํ•˜๋‹ค๋ณด๋‹ˆ ๋ถˆํŽธํ•˜๋‹ˆ
ํ•œ๋ฒˆ์— react์™€ json-server๋ฅผ ์‹คํ–‰ ์‹œํ‚ค๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!
๐Ÿ‘‡๐Ÿ‘‡

๐Ÿ“˜ concurrently

โœ… concurrently ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•˜์—ฌ React์™€ json-server ํ•œ๋ฒˆ์— ์‹คํ–‰ํ•˜๊ธฐ.

 npm install concurrently --save

๐Ÿ”— ์ฐธ๊ณ 
https://www.npmjs.com/package/concurrently

โœ”๏ธ package.json์—์„œ concurrently ์„ค์น˜ ํ™•์ธ.

โœ… package.json์—์„œ scripts dev๋ฅผ ์ถ”๊ฐ€ํ•ด์„œ ํ…Œ์ŠคํŠธ

"dev": "concurrently \"npm run start\" \"json-server ./data/data.json --port 4000\""

โœ”๏ธ npm run dev ๋ฅผ ์‹คํ–‰
localhost:3000
localhost:4000/test
ํ™•์ธ ์™„๋ฃŒ๐Ÿ‘

๐Ÿ‘‡ axios ํ…Œ์ŠคํŠธ ์ง„ํ–‰!!

๐Ÿ“˜ Axios - GET, POST, PUT, DELETE

๐Ÿ“ GET ํ…Œ์ŠคํŠธ

import axios from "axios"

function AxiosTest(){
  axios.get("http://localhost:4000/test")
    .then((res) => {
      console.log(res)
    })
    .catch((err) => {
      console.log(err)
    })
  return (
    <>
    </>
  )
}
export default AxiosTest;

โœ”๏ธ ํ™•์ธ

โœ… ERROR

// โš ๏ธ ์ž˜๋ชป๋œ ์ฃผ์†Œ ์ž…๋ ฅ.
axios.get("http://localhost:4000/velog")
  .then((res) => {
    console.log(res)
  }) 
  .catch((err) => {
    console.log(err)
  })

๐Ÿ“ POST ํ…Œ์ŠคํŠธ

import axios from "axios"
function AxiosTest(){
  const addData = {
    name:"์ด๋ฆ„6",
    desc:"ํ…Œ์ŠคํŠธ ์ค‘6"
  }
  axios.post("http://localhost:4000/test",addData)
    .then((res) => {
      console.log(res)
    })
    .catch((err) => {
      console.log(err)
    })
  return (
    <>
    </>
  )
}
export default AxiosTest;

โš ๏ธ ๋ Œ๋”๋ง ์‹œ axios.post๊ฐ€ ์‹คํ–‰ ๋˜์–ด์„œ ์—ฌ๋Ÿฌ๊ฐœ๊ฐ€ ์ถ”๊ฐ€๊ฐ€ ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
useEffect ๋˜๋Š” ์–ด๋– ํ•œ ๋ฐ˜์‘์— ์˜ํ•ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์‹คํ–‰ ํ•˜๋„๋ก ์ˆ˜์ • ํ•ด์ฃผ์„ธ์š”!

๐Ÿ“ PUT ํ…Œ์ŠคํŠธ

import axios from "axios"

function AxiosTest(){
  const putChange = () => { // ํด๋ฆญ ์‹œ ๋ณ€๊ฒฝํ•˜๋„๋ก
    axios.put("http://localhost:4000/test/4",{
      name:"velog",
      desc:"์•„์ด๋””4๋กœ ๋ณ€๊ฒฝ"
    })
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.log(err);
    })
  }
  return (
    <>
      <button 
    	type="button" 
    	onClick={() => putChange()}>
    	ID 4 ๋ณ€๊ฒฝํ•˜๊ธฐ
   	  </button>
    </>
  )
}
export default AxiosTest;

โœ”๏ธ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ - ์ˆ˜์ • ์™„๋ฃŒ!

โœ”๏ธ json ํŒŒ์ผ ํ™•์ธํ•˜๋ฉด ๋ณ€๊ฒฝ์ด ๋˜์–ด ์žˆ๋‹ค.

๐Ÿ“ DELETE

import axios from "axios"

function AxiosTest(){
  const axiosDelete = () => { // id 5 ์‚ญ์ œ
    axios.delete("http://localhost:4000/test/5")
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.log(err);
    })
  }
  return (
    <>
      <button 
    	type="button" 
    	onClick={() => axiosDelete()}>
    	ID 5 ์‚ญ์ œํ•˜๊ธฐ
      </button>
    </>
  )
}
export default AxiosTest;

โœ”๏ธ ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ - ์‚ญ์ œ ์™„๋ฃŒ!

โœ”๏ธ json ํŒŒ์ผ ํ™•์ธ

๐Ÿ“ํ…Œ์ŠคํŠธ์šฉ

import axios from "axios"
function AxiosTest(){
  const axiosGet = () => {
    axios.get("http://localhost:4000/test")
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.log(err);
    })
  } 
  const axiosPost = () => {
    axios.post("http://localhost:4000/test",{
      name:"์ถ”๊ฐ€!",
      desc:"Post"
    })
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.log(err);
    })
  }
  const axiosPut = () => { // โš ๏ธ id๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ error
    axios.put("http://localhost:4000/test/4")
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.log(err);
    })
  }
  const axiosDelete = () => {  // โš ๏ธ id๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ error
    axios.delete("http://localhost:4000/test/6")
    .then((res) => {
      console.log(res);
    })
    .catch((err) => {
      console.log(err);
    })
  }
  return (
    <>
      <button type="button" onClick={() => axiosGet()}>ํ™•์ธ</button>
      <hr />
      <button type="button" onClick={() => axiosPost()}>์ถ”๊ฐ€</button>
      <hr />
      <button type="button" onClick={() => axiosPut()}>ID 4 ๋ณ€๊ฒฝํ•˜๊ธฐ</button>
      <hr />
      <button type="button" onClick={() => axiosDelete()}>ID 5 ์‚ญ์ œํ•˜๊ธฐ</button>
    </>
  )
}
export default AxiosTest;

โœ… ๊ฐ„๋‹จํ•˜๊ฒŒ get, post, put, delete ํ™•์ธ ์™„๋ฃŒ ๐Ÿ‘

๐Ÿ“— Axios ํ…Œ์ŠคํŠธ-์ถ”๊ฐ€, ์‚ญ์ œ, ์ฒดํฌ ๋ณ€๊ฒฝ

import axios from "axios"
import { useEffect, useState } from "react";
import styled from "styled-components";
function AxiosTest(){
  const [listData, setlistData] = useState([]); // default []
  const URL = "http://localhost:4000/test";

  // ์ดˆ๊ธฐ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
  const loadAxios = async() => {
    try {
      const res = await axios.get(URL)
      setlistData(res.data); // state data ๊ฐ’ ์ž…๋ ฅ
    }catch(error) {
      console.log(error)
    }
  }
  // ์ถ”๊ฐ€
  const postAxios = async(pushData) => { // ์ˆ˜์ •ํ•˜๋Š” item, ์ˆ˜์ • ๊ฐ’
    try{
      await axios.post(`${URL}`, {...pushData})
    }catch(error) {
      console.log(error)
    }
  }
  // checked ์ˆ˜์ •
  const putAxios = async(putItem, putData) => { // ์ˆ˜์ •ํ•˜๋Š” item, ์ˆ˜์ • ๊ฐ’
    try{
      await axios.put(`${URL}/${putItem.id}`, { ...putItem, ...putData})
    }catch(error) {
      console.log(error)
    }
  }
  // ์‚ญ์ œ
  const deleteAxios = async(putItem) => { // ์‚ญ์ œ ๋ฐ์ดํ„ฐ
    try{
      await axios.delete(`${URL}/${putItem.id}`)
    }catch(error) {
      console.log(error)
    }
  }

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

  const addItem = () => { // ์ถ”๊ฐ€ ๋ฒ„ํŠผ
    const testData = {
      id: `test_${Math.random() * 1000}`,
      name:"ํ…Œ์ŠคํŠธ Name",
      checked:false
    };
    // setlistData(prev => [...prev, testData])
    setlistData(prev => prev.concat(testData))
    postAxios(testData);
  }
  const toggleChecked = (liItem) => { // ์ˆ˜์ • ๋ฒ„ํŠผ
    const toggleCheck = {
      checked: !liItem.checked
    }
    setlistData(
      listData.map(item => 
        item.id === liItem.id ? {...item, ...toggleCheck}: item
      )
    )
    putAxios(liItem, toggleCheck); // axios put ์š”์ฒญ
  }
  const removeItem = (liItem) =>{  // ์‚ญ์ œ ๋ฒ„ํŠผ
    setlistData(
      listData.filter(item => 
        item.id !== liItem.id && item
      )
    )
    deleteAxios(liItem);
  }
  return (
    <div>
      <AddBtnStyle onClick={() => addItem()}>์ถ”๊ฐ€ํ•˜๊ธฐ</AddBtnStyle>
      <hr />
      <ul>
        {
          listData.map((item,idx) => {
            return <LiStyle key={idx}>
              <p>name: {item.name}</p>
              <button type="button" onClick={()=>toggleChecked(item)}>
                {item.checked ? 'โœ…' : 'โฌœ' }
              </button>
              <button type="button" onClick={()=>removeItem(item)}>โŒ</button>
            </LiStyle>
          })
        }
      </ul>
    </div>
  )
}
export default AxiosTest;

// styled-component
const AddBtnStyle = styled.button.attrs({
  type:'button'
})`
  margin:10px 0;
  padding:5px;
  border:1px solid #dbdbdb;
  background:transparent;
  cursor:pointer;
`;
const LiStyle = styled.li`
  margin-top:5px;
  border-top:1px solid #dbdbdb;
  & > button {
    margin:0 2px;
    padding:5px; 
  }
`;

โœ… ๐Ÿ‘† ํ…Œ์ŠคํŠธ์šฉ

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜

profile
๊ณต๋ถ€&๊ธฐ๋ก

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