React에서 서버에 데이터 요청하는 방법

    반응형

    01. 서버 만들기

     

    01) express 설치

     

    ① 터미널에 아래와 같이 입력

    npm i express

     

    ② app.js에 샘플 코드 입력

    const express = require('express');
    const app = express();
    
    app.get('/', function (req, res) {
      res.send('Hello World');
    });
    
    app.listen(4000, () => {
      console.log('server start');
    });

     

    ③ 연결이 잘 됐나 확인

    node app.js

    실행화면

     

    02) 가상의 데이터로 get, post 테스트 하기

    ① body-parser를 사용하기 위해 코드 추가

    app.use(express.json()) // for parsing application/json
    app.use(express.urlencoded({ extended: true })) // for parsing application/x-www-form-urlencoded
    • body-parser : 클라이언트에서 body에 담은 데이터를 꺼내쓰기 좋게 해주는 parser
    • express에서 body에 있는 데이터를 꺼내 쓰려면 'body-parser'가 필요함

    ② 임시로 데이터 'todoList' 생성

    let id = 2;
    const todoList = [{ id: 1, text: '할일', done: false }];

     

    'todoList' 목록 가져오기 (Get)

    app.get('/api/todo', (req, res) => {
      res.json(todoList);
    });

    실행화면

     

    'todoList' 값 추가하기 (Post)

    app.post('/api/todo', (req, res) => {
      const { text, done } = req.body;
      todoList.push({
        id: id++,
        text,
        done,
      });
      return res.send('success');
    });

     

    - postman으로 테스트

    post 실행 화면

     

    - 추가한 값이 잘 들어온 것을 확인할 수 있음

     

     

    ⑤ 최종 코드

    const express = require('express');
    const app = express();
    app.use(express.json()); // for parsing application/json
    app.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
    
    let id = 2;
    const todoList = [{ id: 1, text: '할일', done: false }];
    
    app.get('/', function (req, res) {
      res.send('Hello World');
    });
    
    app.get('/api/todo', (req, res) => {
      res.json(todoList);
    });
    
    app.post('/api/todo', (req, res) => {
      const { text, done } = req.body;
      todoList.push({
        id: id++,
        text,
        done,
      });
      return res.send('success');
    });
    
    app.listen(4000, () => {
      console.log('server start');
    });

     

     

    02. 리액트 프로젝트 생성

     

    ① 터미널에 아래와 같이 입력

    npx create-react-app .

     

    ② 'npm start'하고 잘 되는지 확인

    실행화면

     

     

    03. 서버에 데이터 요청하기

     

    01) fetch

    • 기본으로 제공하는 api 가져오는 내장 함수
    • 서버에 데이터를 요청하려면 서버 주소 HTTP method가 필요함
    import { useEffect, useState } from 'react';
    
    function App() {
      const [todoList, setTodoList] = useState(null);
    
      const fetchData = () => {
        fetch('http://localhost:4000/api/todo')
          .then((response) => response.json())
          .then((data) => setTodoList(data));
      };
    
      useEffect(() => {
        fetchData();
      }, []);
    
      const onSubmitHandler = (e) => {
        e.preventDefault();
        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' />
            <input name='done' type='checkbox' />
            <input type='submit' value='추가' />
          </form>
          {todoList &&
            todoList.map((todo) => (
              <div key={todo.id} style={{ display: 'flex' }}>
                <div>{todo.id}</div>
                <div>{todo.text}</div>
                <div>{todo.done ? 'Y' : 'N'}</div>
              </div>
            ))}
        </div>
      );
    }
    
    export default App;

    fetchData : 서버에서 값을 가져오는 코드를 함수로 생성

    fetch : 인자로  서버 주소를 적고, 응답값을 json 형태로 파싱

    useEffect() : 처음 렌더링 될 때 한번만 값 가져오기

    e.preventDefault(); : form의 submit 기본 동작인 get 요청을 막아줌

    headers : 보내준 데이터가 json 형태라고 명시해줘야 바디에서 파싱할 때 json 형태로 파싱해서 사용할 수 있음

    JSON.stringify() : 객체를 JSON 문자열로 반환

    실행화면

     

     

     

    🚨CORS 에러

    CORS 에러 console 창
    • 서버에 요청할 때 자주나는 에러
    • CORS(Cross Origin Resource Sharing) : origin이 달라서 데이터를 가져올 수 없다는 정책
    • 현재 client는 'localhost:3000', server는 'localhost:4000'를 사용하고 있음
    • client와 server의 origin(host와 port를 포함한 데이터의 출처)이 달라서 생기는 문제
    • 서버에서 이 문제를 해결해줘야 함

    💡해결방법

     

    - ① origin이 다를 때 허용해주는 라이브러리 다운로드

    npm i cors

     

     - ② import하고 middleware 추가

    const cors = require('cors');
    
    app.use(cors());
     

     

    02) axios

    • 라이브러리를 사용해서 api 가져오기

    ① axios 설치

    npm i axios
    import axios from 'axios';

     

    ②  fetch 코드에서 axios로 변경

    import { useEffect, useState } from 'react';
    import axios from 'axios';
    
    const server_url = 'http://localhost:4000/api/todo';
    function App() {
      const [todoList, setTodoList] = useState(null);
      const fetchData = async () => {
        const response = await axios.get(server_url);
        setTodoList(response.data);
      };
    
      useEffect(() => {
        fetchData();
      }, []);
    
      const onSubmitHandler = async (e) => {
        e.preventDefault();
        const text = e.target.text.value;
        const done = e.target.done.checked;
        await axios.post(server_url, { text, done });
        fetchData();
      };
      return (
        <div className='App'>
          <h1>TODO LIST</h1>
          <form onSubmit={onSubmitHandler}>
            <input name='text' />
            <input name='done' type='checkbox' />
            <input type='submit' value='추가' />
          </form>
          {todoList &&
            todoList.map((todo) => (
              <div key={todo.id} style={{ display: 'flex' }}>
                <div>{todo.id}</div>
                <div>{todo.text}</div>
                <div>{todo.done ? 'Y' : 'N'}</div>
              </div>
            ))}
        </div>
      );
    }
    
    export default App;

    axios.post : 옵션을 따로 추가하지 않고 메서드로 get인지 post인지 명시

    { text, done } : 직렬화 하지 않고 비 구조화 할당으로 값을 보냄

    실행화면

     

     

     

    참고자료

    라매개발자, '프론트에서 서버에 데이터 요청하는 방법 (React로 fetch, axios 사용하기)'

     

    반응형

    댓글