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

 

반응형

댓글