ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Axios
    React 2022. 12. 20. 08:59

    Axios

    Axios란

    • 공식문서에 따르면 axios 란 node.js와 브라우저를 위한 Promise 기반 http 클라이언트 라고 소개하고 있음. 다시 말해 http를 이용해서 서버와 통신하기 위해 사용하는 패키지라고 생각하면 됨

    Axios tjfcl

    yarn add axios
    

    Axios 공식문서

    • 요청 config에 어떤게 들어갈 수 있는지 확인할 수 있다.

    https://axios-http.com/kr/docs/req_config

    json-server 공식문서

    • Get요청 config에 어떤게 들어갈 수 있는지 확인할 수 있다.

    https://www.npmjs.com/package/json-server

    백엔드 개발자와 협업 할 때에는 백엔드 개발자와 소통을 해서 요청방법을 알아낼 수 있는데,

    json-server는 패키지에서 알려주는대로 요청을 해야 정상적으로 데이터를 가져올 수 있다.

    Plural routes

    GET    /posts
    GET    /posts/1
    POST   /posts
    PUT    /posts/1
    PATCH  /posts/1
    DELETE /posts/1
    

    첫번째 줄은, posts를 GET 하겠다는 뜻,

     

    Filter

    Use . to access deep properties

    GET /posts?title=json-server&author=typicode
    

    쿼리를 보내는 경우는 이런식이다.

    물음표 (?) 뒤에 오는 것 들을(title=json-server&author=typicode) 쿼리 라고 한다.

    제목이 json-server 이고 author가 typicode인 것을 가지고 오라는 뜻이다.

    보통 정해진 id를 사용해서 넘겨주는 경우 path variable을 사용해서 api 명세를 작성하고,

    검색기능, 또는 특정 값을 찾을 때에는 query를 통해서 사용하게 된다.

    GET 사용해보기

    • Axios 테스트를 위해 db.json 설정
    // 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;
    

    콘솔에 데이터에 저장된 todos가 잘 나오고 있다.

    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;
    

    데이터가 저장이 되었기 때문에 새로고침을 해도 남아있다.

    네트워크 탭 확인하기<<중요

    post 요청을 보냈을 때 브라우저의 네트워크 탭에서 어떤 로그가 생기는지 확인해야 한다.

    어떤 문제가 생겼을 때 이 정보를 통해서 디버깅을 할 수 있기 때문,

    headers

    • 요청 Method를 통해서 우리가 POST 메서드를 사용했음을 알 수 있습니다.
    • 요청 URL을 통해서 우리가 의도한 URL로 post 요청을 보냈음을 알 수 있습니다.
    • 상태 코드를 통해서 201 코드를 받았고, 정상적으로 네트워크가 이루어졌음을 알 수 있습니다. 상태 코드는 자동으로 생성되는 것이 아니라 BE개발자가 직접 개발을 하고 설정한 code가 브라우저에게 보이게 됩니다. 그래서 만약 BE개발자가 구현을 해놓지 않았다면 문맥과 다른 상태 코드가 브라우저에 보일 수 있습니다.
    • 그 밖에도 request headers와 response headers 정보가 추가적으로 있습니다. 이 부분은 각 항목들이 어떤 것을 우리게 보여주는지 더 알아보시길 바랍니다.
    • headers

    • Request URL을 통해서 우리가 의도한 URL로 post 요청을 보냈음을 알 수 있습니다.
    • Request Method를 통해서 우리가 POST 메서드를 사용했음을 알 수 있습니다.
    • Status Code를 통해서 201 코드를 받았고, 정상적으로 네트워크가 이루어졌음을 알 수 있습니다. status code는 자동으로 생성되는 것이 아니라 BE개발자가 직접 개발을 하고 설정한 code가 브라우저에게 보이게 됩니다. 그래서 만약 BE개발자가 구현을 해놓지 않았다면 문맥과 다른 status code가 브라우저에 보일 수 있습니다.
    • 그 밖에도 응답 헤더와 요청 헤더 정보가 추가적으로 있습니다. 이 부분은 각 항목들이 어떤 것을 우리게 보여주는지 더 알아보시길 바랍니다.

     

     

    • payload

    • payload에서는 우리가 보낸 body를 확인 할 수 있습니다. 우리가 보낸 값이 정상적으로 보입니다.
    1. response

    • response에서는 우리가 보낸 post에 요청에 대한 서버의 응답값을 확인할 수 있습니다. 이 Response 값은 자동으로 생성되는 것이 아니라, FE 개발자가 BE 개발자에게 요청한 것을 직접 개발을 해야 생기는 값입니다. 우리가 사용한 json-server의 경우 POST 요청을 했을 때, 클라이언트가 보낸 body를 그대로 응답해주도록 만들어져 패키지이기 때문에 위와 같이 표시됩니다.

    DELETE 사용해보기

    GET, POST 와 함께 코드가 작성됩니다. onClickDeleteButtonHandler 와 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 번외

    • 삭제를 누르면 바로 없어지게 하고싶어서 코드를 약간 수정했다.
     const onClickDeleteButtonHandler = (todoId) => {
        axios.delete(`http://localhost:3001/todos/${todoId}`);
        setTodos([...todos, todoId]);
      };
    

    근데 아래 사진과 같이 삭제를 누르면 빈 데이터가 1개 생기고, 새로고침을 해야지만 정상적으로 삭제가 됐다.

    튜터님에게 도움을 빌려 힌트를 얻고, filter를 통해 삭제를 진행해보았다.

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

    이렇게 해주니 딜레이 없이 바로 삭제되는 것을 경험했다.

    PATCH(수정) 사용해보기

    PUT과 PATCH의 차이점

    • PUT - 리소스의 모든 것을 업데이트(전부 다 수정요청을 안해주면 요청한 부분 빼고는 null로 나옴)
    • PATCH - 요청하는 부분만 업데이트(기존 데이터를 유지)

    TODO를 수정하고자 할 때 필요한 데이터

    • 수정하고자 하는 Todo의 id ( 직접 입력하여 url로 넘김 )
      • 보통 수정기능 만들 때 직접 id를 입력받아 처리하는 방식은 거의 없음.
    • 수정하고자 하는 값 ( 기존에 있던 todo라는 state 사용 )

    정리

    • Axios를 이용해서 API 서버와 통신할 수 있다.
    • Axios는 http 통신을 도와주는 패키지이며, 구체적인 명세는 API 명세서를 확인해야 한다.
    • 브라우저 네트워크 탭을 잘 봐야 한다.
    • http method, staus code와 같은 정보들은 BE개발자가 구현해주는 부분이며, 약속이자 문맥이므로 BE와 FE간의 커뮤니케이션이 잘 되어야 한다.
    • 네트워크 통신 이후, 화면을 업데이트 하고자 한다면 별도로 FE에서 추가로 구현해야 한다.
    GET /posts?title=json-server&author=typicode
    

    쿼리를 보내는 경우는 이런식이다.

    물음표 (?) 뒤에 오는 것 들을(title=json-server&author=typicode) 쿼리 라고 한다.

    제목이 json-server 이고 author가 typicode인 것을 가지고 오라는 뜻이다.

    보통 정해진 id를 사용해서 넘겨주는 경우 path variable을 사용해서 api 명세를 작성하고,

    검색기능, 또는 특정 값을 찾을 때에는 query를 통해서 사용하게 된다.

    •  

    'React' 카테고리의 다른 글

    styled component porps해서 쓰기  (0) 2022.12.20
    Redux(3) - react-router-dom, props children, Dynamic Route  (0) 2022.12.20
    Json-server  (0) 2022.12.20
    Redux Toolkit  (0) 2022.12.20
    Redux(2)-action creator, payload  (0) 2022.12.19
Designed by Tistory.