[React] Axios CRUD In React

안치영·2022년 10월 20일
1

React

목록 보기
11/15

🔥 AXIOS??

node.js 와 브라우저를 위한 Promise 기반 http 클라이언트이다.
다시말해 http를 이용해 서버와 통신하기 위해 사용하는 패키지이다.

Axios 설치 명령어

yarn add axios

API서버는 FE에서 만드는 json-server를 사용한다.
필자는 로컬환경에서 실행할 것 이기에, 프로젝트 내의 3001번 포트를 사용한다.

🔥 Axios CRUD 요청

GET 은 서버의 데이터를 조회할 때 사용한다.
CRUD의 R(Read) 부분을 맡고 있다.

POST 는 서버에 데이터를 추가할 때 사용한다. 다만 post 요청에 의한 로직은 BE개발자가 구현하는 것이기에, 추가 외에 다른용도로도 사용할 수는 있지만, 보통은 클라이언트의 데이터를 body형태로 서버에 보내고자 할 때 사용한다. CRUD의 C(Create) 부분을 맡고 있다.

post 요청을 성공적으로 마쳤으면 브라우저에서 새로고침을 통해 확인할 수 있다. 추가적으로 브라우저의 네트워크 탭에서 로그를 확인해보면, Status Code를 통해서 200, 201, 404 등등 로그를 확인할 수 있다.

DELETE 는 말그대로 저장되어있는 데이터를 삭제하고자 요청을 보낼 때 사용한다. CRUD의 D(Delete) 부분을 맡고 있다.

PATCH 는 어떤 데이터를 수정하고자 서버에 요청을 보낼 때 사용하는 메서드이다. 다만, 이것은 http환경에서 서로가 한 약속이자 문맥이기 때문에, 수정을 하고자 반드시 patch,put을 사용해야하는 것은 아니다.
BE에 의해서 Post로도 충분히 수정을 할 수가 있지만, 개발자들의 약속이기에 patch를 사용한다.
CRUD의 U(Update) 부분을 맡고 있다.

axios로 요청할 때의 코드

axios.get(url[, config])
axios.post(url[, config])
axios.delete(url[, config])
axios.patch(url[, config])

위의 코드가 기본 모양이다.

저는 json-server에 있는 todos를 axios를 이용해서 fetching 하고 useState를 통해서 관리하는 로직을 짜보려 합니다.

// GET 방식
const App = () => {
  const [todos, setTodos] = useState(null);
	// axios를 통해서 get 요청을 하는 함수를 생성
	// 비동기처리를 해야하므로 async/await 구문을 통해서 처리
  const fetchTodos = async () => {
    // Axios Get 사용법
    const { data } = await axios.get("http://localhost:3001/todos");
    setTodos(data); // 서버로부터 fetching한 데이터를 useState의 state로 set.
  };

// POST 방식
const onSubmitHandler = (todo) => {
    axios.post("http://localhost:3001/todos", todo); // Axios Post 사용법
  };

// DELETE 방식
const onClickDeleteButtonHandler = (todoId) => {
    axios.delete(`http://localhost:3001/todos/${todoId}`); // Axios Delete 사용법
  };
  
// PATCH 방식
const onClickEditButtonHandler = (todoId, edit) => {
    axios.patch(`http://localhost:3001/todos/${todoId}`, edit); // Axios Patch 사용법
  };
    
  };

완성된 코드

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

  // axios를 통해서 get 요청을 하는 함수를 생성합니다.
  // 비동기처리를 해야하므로 async/await 구문을 통해서 처리합니다.
  // GET 부분
  const fetchTodos = async () => {
    const { data } = await axios.get("http://localhost:3001/todos");
    setTodos(data); // 서버로부터 fetching한 데이터를 useState의 state로 set 합니다.
  };
  
  // POST 부분
  const onSubmitHandler = async (todo) => {
    await axios.post("http://localhost:3001/todos", todo);
    setTodos((prev) => [...prev, todo]);
    fetchTodos();
    setTodo({ title: "" });
  };
  
  // DELETE 부분
  const onClickDeleteButtonHandler = async (todoId) => {
    await axios.delete(`http://localhost:3001/todos/${todoId}`);
    const newTodos = todos.filter((todo) => {
      return todo.id !== todoId;
    });
    setTodos(newTodos);
  };
  
  // PATCH 부분
  const onClickEditButtonHandler = async (todoId, edit) => {
    await axios.patch(`http://localhost:3001/todos/${todoId}`, edit);
    fetchTodos();
    setTargetId("");
    setEditTodo({ title: "" });
  };

  // 생성한 함수를 컴포넌트가 mount 됐을 떄 실행하기 위해 useEffect를 사용
  useEffect(() => {
    (async () => await fetchTodos())();
  }, []);

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault();
          onSubmitHandler(todo);
        }}
      >
        <div>
          <input
            type="text"
            placeholder="수정하고싶은 Todo ID"
            value={targetId}
            onChange={(ev) => {
              setTargetId(ev.target.value);
            }}
          />
          <input
            type="text"
            placeholder="수정값 입력"
            value={editTodo.title}
            onChange={(ev) => {
              setEditTodo({
                ...editTodo,
                title: ev.target.value,
              });
            }}
          />
          <button
            // type='button' 을 추가해야 form의 영향에서 벗어남
            type="button"
            onClick={() => onClickEditButtonHandler(targetId, editTodo)}
          >
            수정하기
          </button>
        </div>
        <input
          type="text"
          value={todo.title}
          onChange={(ev) => {
            const { value } = ev.target;
            setTodo({
              ...todo,
              title: value,
            });
          }}
        />
        <button>추가하기</button>
      </form>
      <div>
        {todos?.map((todo) => (
          <div key={todo.id}>
            {todo.id} :{todo.title}
            <button type="button" onClick={() => onClickDeleteButtonHandler(todo.id)}>
              삭제하기
            </button>
          </div>
        ))}
      </div>
    </>
  );
};

export default App;

0개의 댓글