1차 공부/React공부

Axios

공대탈출 2022. 12. 10. 23:54

Axios란 node.js와 브라우저를 위한 promise기반 http클라이언트 입니다.

쉽게말해 http를 이용해 서버와 통신하기위해 사용하는 패키지입니다.

 

json server 데이터를 아래와 같이 설정한다.

{
  "todos": [
    {
      "id": "1",
      "title": "react"
    }
  ]
}

 

먼저 axios get에 대해 보자.

get는 서버의 데이터를 조회할 때 사용합니다.

// 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;

useEffect를 사용해서 컴포넌트가 처음 마운트 될 때 서버로부터 todos의 데이터를 get한 것을 볼 수 있습니다.

 


다음으로 axios post입니다.

post는 보통 서버에 데이터를 추가할 때 사용합니다.

아래코드는 인풋과 버튼이있고 어떤 값을 넣고 버튼을 눌렀을 때 특정 함수가 실행되어,

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 = async(todo) => {
    //1.  이때 todos는 [{투두하나}]임
    await axios.post("http://localhost:3001/todos", todo); // 이때 서버에 있는 todos도 [{투두하나}]임
    // 근데 여기서 서버 요청이 끝나고 서버는 [{투두가},{두개임}]
    setTodos([...todos, todo]) 2. <-- 만약 이게 없다면, go to useEffect
    //4. 새로고침해서 진짜 현재 서버 데이터를 받아오기전에 상태를 똑같이 동기시켜줌 
    //5. 어떻게보면 유저한테 서버에서 새로 받아온것처럼 속이는거지
		
  };

  useEffect(() => {
    fetchTodos(); //3. 새로고침해서 여기를 다시 실행해줘야 서버값이 새로 들어옴 e.g) [{투두가},{두개임}]
  }, []);

  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;

 

다음으로 delete입니다.

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: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입니다.

patch는 보통 어떤 데이터를 수정하고자 서버에 요청을 보낼 때 사요하는 메서드입니다.

 

Todo를 수정하기 위해선 수정하고자하는 Todo의 id, 그리고 수정하고자하는 값이 필요합니다.

수정하고자하는 값은 기존에 있던 todo라는 state를 사용하면 될 것이고, id는 직접 입력을 해서 url로 넘겨주는 방식으로 구현하였습니다.

 

보통 수정기능을 만들 때 id를 입력받아 처리하는 방식은 거의 없지만, 이번에는 간단한 코드로 기능을 구현하기 때문에 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;

'1차 공부 > React공부' 카테고리의 다른 글

thunk가 뭔데 도대체  (0) 2022.12.13
Axios관련 더 알아보기  (0) 2022.12.11
json server  (0) 2022.12.10
immer란?  (0) 2022.12.10
Flux과 Redux (정리필요)  (0) 2022.12.10