9시 24분
React + Node.js 연동 본문
이제 프론트엔드 작업이 얼추 끝났으니 백엔드로 다시 돌아가자!
서버 연동
리액트와 노드가 정보를 주고 받기 위해서는 리액트 서버, 노드 서버를 동시에 열 수 있어야 한다.
두 서버를 동시에 여는 것은 간단한데, 포트 번호를 다르게 하면 된다.
https://leeeeeyeon.tistory.com/96을 참고하여 기초적인 express 환경을 갖추자.
이제 포트 번호를 바꿔보자. 포트 번호는 bin/www 파일에서 바꿀 수 있다.
15~16줄에 아래와 같은 코드가 있는데 3000을 3002, 8000 등 다른 번호로 바꾸어주자.
var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);
Server side > Client로 데이터 받아오기
이제 클라이언트 사이드(프론트엔드, 리액트)에서 서버 사이드(백엔드, 노드)에게 정보를 요청하여 받아와보자.
데이터를 받아오는 것을 연습하기 위하여 클라이언트 사이드에 api라는 route을 만들어주자.
- routes 폴더에 Api.js 파일 생성
- App.js에서 api route 만들기
- Navigation.js에서 '/api'로 접속할 수 있는 네비게이션 만들기
// Api.js
import React from 'react';
import axios from 'axios';
class Api extends React.Component{
state = {
isLoading: true,
data: []
}
getApi = async () => {
const {data} = await axios.get("http://localhost:3002/api");
this.setState({data, isLoading: false}); }
async componentDidMount(){
this.getApi();
}
render(){
const {isLoading, data} = this.state;
return (
<section>
{isLoading ?
<div>
<span>Loading...</span>
</div>
:
<div style={{position: 'absolute', top: '50%', left: '50%'}}>
<h3>{data.success}</h3>
</div>
}
</section>
);
}
}
export default Api;
두둥! 나도 드디어 만났다 CORS 에러 ,,, !
CORS(Cross-Origin Resource Sharing)는 동일한 도메인이 아닌 다른 도메인에 리소스를 요청할 시에 서로 다른 origin에 대하여 HTTP 요청이 가능하게 해주는 표준이다.
브라우저에서는 보안상의 이유로 다른 도메인에서 허용하지 않은 요청에 대하여 제한하고 있어 CORS 에러가 발생한다.
우리의 경우, 클라이언트는 localhost:3000, 서버는 localhost:3002를 사용하여 발생한 것이다.
이를 해결하는 방법은
- 서버 측에서 Access-Control-Allow-Origin 접근권한 설정
- JSONP 설정
- Proxy 설정
등 여러 방법이 있다.
처음에는 http-proxy-middleware을 사용하여 proxy를 설정하는 방법을 사용해봤지만, 잘 되지 않아 Access-Control-Allow-Origin을 설정하는 방법을 택했다.
서버 단으로 가서 cors 미들웨어를 설치해준다.
npm install cors --save
그리고 app.js에
var cors = require('cors');
app.use(cors());
를 추가해준다.
그리고 Api.js의 코드를 작성할 때 처음에
<h3>{data.success}</h3>
이 아닌
<h3>{data}</h3>
라고 하니 아래와 같은 오류가 발생하였다.
이는 우리가 객체 데이터를 그대로 렌더링하였기 때문에 발생한 것이다. 그러므로 객체 자체를 렌더링하지말고 객체의 요소를 이용하여 접근하자.
리액트 노드 연동 성공 ~~ !! \(゚ー゚\) ~~ ( ノ ゚ー゚)ノ
Client > Server로 데이터 전송하기
며칠동안 서버로 데이터 전송하는게 안됐는데 드디어 성공했다 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
우선 클라이언트 단의 Api.js를 useState와 useEffect를 이용하여 리팩토링하였다.
import React, { useEffect, useState } from "react";
import axios from "axios";
function Api(){
const [loading, setLoading] = useState(false);
const [data, setData] = useState(null);
const [error, setError] = useState(null);
useEffect( () => {
const getApi = async () => {
try{
setError(null);
setData(null);
setLoading(true);
const response = await axios.get('http://localhost:3002');
setData(response.data);
} catch (error){
setError(error);
}
setLoading(false);
};
const postApi = () => {
axios.post('http://localhost:3002/post',
{
userName: 'leeeeeyeon'
},
{
headers: {
'Content-type': 'application/json',
'Accept': 'application/json'
}
}
)
.then(() => { console.log('client - send post data'); })
.catch((error) => { console.log(error); });
};
getApi();
postApi();
}, []);
if (loading) return <div>Loading...</div>;
if(error) return <div>Error!</div>
if(!data) return null;
return (
<div style={{position: 'absolute', top: '5%', left: '15%'}}>
<h3>{data.success}</h3>
</div>
);
}
export default Api;
클라이언트에서 서버로 데이터를 전송하는 함수가 postApi()이다.
axios.post를 이용해주었으며, 첫 번째 인자로 데이터를 전송할 url을, 두 번째 인자로 전송할 데이터를, 세 번째 인자로 헤더를 주었다.
then에는 데이터 전송에 성공했을 때의 코드를, catch에는 에러가 발생하였을 시의 코드를 작성했다.
그리고 서버에는 아래와 같이 요청을 받는 코드를 작성하여주었다.
router.post('/post', function(req, res, next){
console.log('server - recieved data from client');
console.log(req.body);
});
참고
- https://singa-korean.tistory.com/46
- https://fullmoon1344.tistory.com/145
- https://cbw1030.tistory.com/267
- https://hololo-kumo.tistory.com/147
- https://devport.tistory.com/13
- https://velog.io/@bigbrothershin/React-Objects-are-not-valid-as-a-React-child-%EC%97%90%EB%9F%AC-%EC%B2%98%EB%A6%AC
- https://darrengwon.tistory.com/337
- https://velog.io/@jakeseo_me/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B3%B5%EC%8B%9D%EB%AC%B8%EC%84%9C%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90-9-%ED%8F%BC
- https://react.vlpt.us/integrate-api/01-basic.html
- https://hoony-devblog.tistory.com/6
- https://semtax.tistory.com/7
'Javascript' 카테고리의 다른 글
Typescript로 블록체인 만들기 (0) | 2021.08.23 |
---|---|
게시판 기능 리팩토링 (0) | 2021.08.04 |
게시판 CRUD 기능 만들기 (0) | 2021.08.01 |