[React] Axios로 Express 서버와 연동하기 (4) 서버로 데이터 보내기

쥬롬의 코드착즙기·2022년 11월 3일
1

TIL : Today I learned

목록 보기
7/10
post-thumbnail
post-custom-banner

본문은 라매개발자 강의 프론트에서 서버에 데이터 요청하는 방법 (React로 fetch, axios 사용하기)를 기반으로 작성되었습니다.

📌 서버로 데이터 보내기

투두리스트를 체크해서 서버로데이터를 보내 보자.

📃 form 만들기

react return 문 안에 form을 만들어 준다.
HTML을 안다면 아래 코드는 이해하는 데 무리가 없다고 생각해 설명은 생략한다.
form이 submit될 때 작동할 함수인 onSubmitHandler는 바로 다음에 설명한다.


  return (
    <div className="App">
      <h1>TODO LIST</h1>
      <form onSubmit={onSubmitHandler}>
        <input name="text" type="text"/>
        <input name="done" type="checkbox"/>
        <input value="추가" type="submit"/>
      </form>
      {todoList.map((todo)=>(
//이하생략

📩 onSubmitHandler

form 에서 submit 이벤트가 발생했을 때 (onSubmit), onSubmitHandler를 실행시킨다.

일단 submit 이벤트의 디폴트 행동은 form 태그 안의 데이터를 전송하고 새로고침하는 것이다.
우리는 따로 onSubmitHandler를 통해 데이터를 전송할 것이기 때문에 이 디폴트 행동을 막아야 한다.
React에서는 e.preventDefault();로 막을 수 있다.

  const onSubmitHandler=(e)=>{
    e.preventDefault();

form 태그 안의 데이터를 가져온다.
e.target은 form 태그 안의 HTML이다.
console.log(e.target)을 하면 뭐가 들어오는지 눈으로 확인할 수 있다.

우리한테 필요한 건 text의 입력값과 done의 체크여부이다.
변수로 가져오자.

    const text = e.target.text.value;
    const done = e.target.done.checked;

이제 fetch로 서버에게 POST 요청을 보내 보자.
보낼 때 method, headers, body를 알려줘야 한다.

  • method : HTTP 방식. 기본값이 GET이다. 여기서는 데이터를 전송하는 것이니 POST를 사용한다.
  • headers : HTTP 요청 헤더. 콘텐츠 타입이 JSON이라는 것을 알려준다.
  • body : HTTP 요청 전문. JSON 포맷으로 직렬화하여 보내준다.

fetch를 모두 작성하면 다음과 같다.

fetch('http://localhost:4000/api/todo', {
      method: 'POST',
      headers: {
        "Content-Type": "application/json",
      },
    
      body: JSON.stringify({
        text,
        done,
      })
    })

그러면 추가 버튼을 통해 데이터를 새로 추가할 수 있다.

근데 바로바로 추가가 안 된다.
뭐지? 하고 새로고침을 하면 그제서야 화면에 보인다.
마음에 안 든다. 우리가 상상하고 있는 건 체크하면 바로 화면에 반영되는 것이다.

✅ fetch 수정

바로 화면에 반영되게 하려면 POST를 보내고, 서버에 데이터가 저장되면, 업데이트된 데이터를 다시 GET해오는 것이다.
위 fetch문 뒤에 GET할 때 썼던 부분을 그대로 가져오면 된다.
그런데 복붙하면 같은 코드가 쓸데없이 반복되니까 함수로 모듈화해서 가져오자.

function App() {
  const [todoList, setTodoList] = useState([]);
  
  const fetchData=()=>{
    fetch('http://localhost:4000/api/todo')
    .then((res)=>res.json())
    .then((data)=>setTodoList(data));
  }

  useEffect(() => {
    fetchData();// GET 부분을 fetchData 함수 안으로 집어넣었다
  }, [])



  const onSubmitHandler=(e)=>{
    //생략
    fetch('http://localhost:4000/api/todo', {
      //생략
    })
    .then(fetchData());// 여기서 GET해야 하므로 fetchData를 실행한다
    
  }

그러면 새로고침 없이도 바로바로 반영이 된다.
굿!

📌 전체 코드

client/App.js

import React from "react";
import {useState,useEffect} from "react";



function App() {
  const [todoList, setTodoList] = useState([]);

  const fetchData=()=>{
    fetch('http://localhost:4000/api/todo')
    .then((res)=>res.json())
    .then((data)=>setTodoList(data));
  }

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



  const onSubmitHandler=(e)=>{
    e.preventDefault();
    console.log(e.target);
    const text = e.target.text.value;
    const done = e.target.done.checked;
    fetch('http://localhost:4000/api/todo', {
      method: 'POST',
      headers: {
        "Content-Type": "application/json",
      },
    
      body: JSON.stringify({
        text,
        done,
      })
    })
    .then(fetchData());
    
  }

  return (
    <div className="App">
      <h1>TODO LIST</h1>
      <form onSubmit={onSubmitHandler}>
        <input name="text" type="text"/>
        <input name="done" type="checkbox"/>
        <input value="추가" type="submit"/>
      </form>
      {todoList.map((todo)=>(
        <div>
          <div>{todo.id}</div>
          <div>{todo.text}</div>
          <div>{todo.done ? 'Y' : 'N'}</div>

        </div>
      ))}
    </div>
  );
}

export default App;
profile
코드를 짭니다...
post-custom-banner

0개의 댓글