React

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

PEAZH 2024. 3. 8. 12:59
반응형

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 사용하기)'

 

반응형