[Node.js](개인 프로젝트) React를 적용하다/express + mongoDB + React
React 적용
쇼페이지를 만들려다 버튼을 누름에 따라 항목을 보여주고 싶어졌다. 이를 위해 AJAX가 필요한데, 이를 위해 axios를 사용하기로 했다. axios로 간단한 웹을 만들어 본 적이 있으나 axios를 안 쓴지 오래되서 다시 복습부터 진행하였다.
그런데 문득 뷰를 바꾸는 것 역시 중요하다는 것을 깨달아버렸다. 이를 위해 innerHTML을 바꾸는 방법이나 JQuery를 사용해 볼 수 있겠지만, 전자는 무척 비효율적이며 후자는 점점 죽어가는 기술이라는 것을 알게 된 이 시점에서 굳이 배울 필요가 없어졌다.
그래서 입문 단계만 배워놓은 React를 다시 시작해서 페이지를 구성해야되게 생겼다. 즉 Show 페이지 하나만을 위해 React + axios를 다시 복습하는 것이다.
특정 url에 들어오면(app.get) res.sendFile로 react페이지를 띄우고 해당 리액트 파일 내에서 axios를 이용해서 특정 url로 데이터 요청을 하면. 다시 app.js의 get요청을 받아 res.JSON()으로 데이터를 보내는 방식으로 구현하면 될 것 같다. 사실 될지 안 될지는 해 봐야 알겠지만 우선 목표는 저런 방식으로 구현하는 것이다.
오늘은 이를 위해 버튼 3개를 만들고 누르는 버튼마다 1은 helloworld 출력, 2는 Bye출력, 3은 DB에 저장되어있는 모든 카페 정보를 Json으로 보내서 화면에 출력해보고자 한다.
진행순서
코드
https://github.com/fkthfvk112/YammyPusanUniv
1. 리액트 시작
리액트 시작하기
npx create-react-app my-app //리액트 시작(폴더 및 파일 생성)
npm start react //앱 실행하기
사용한 훅
const _mode = userState(‘값’)
상태를 관리하기 위한 훅이다.
리턴값을 배열.
배열의 첫 요소는 현재 상태의 값, 두 번째 요소는 상태 값을 변경 할 수 있는 함수(setState).
setState가 실행되면 컴포넌트가 다시 랜더링된다.
2. 마주한 에러들
마주한 에러
연결 문제
cors를 사용해야한다.
2. 아래의 문제
: JSON.stringify(value);
^
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'NativeConnection'
| property 'base' -> object with constructor 'Mongoose'
| property 'connections' -> object with constructor 'Array'
--- index 0 closes the circle
at JSON.stringify (<anonymous>)
find를 할 때 await를 하지 않은 사소한 실수. 혹시 await를 한 경우에도 순환참조 에러가 뜬다면 넘기는 요소를 직렬화하면 해결된다.
결론
결국 오늘 하고자 한 것은 해냈다.
기존 app.js에 추가한 것들:
app .get ('/react', async (req , res )=>{
const cafes = await Cafe .find ({})
res .json (cafes );
})
const cors = require ('cors');
app .use (cors ())
리액트 파일 App.js
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
import React , { useState , useEffect } from 'react';
function PageOne (){
return (
<h1 >hello world </h1 >
)
}
function PageTwo (){
return (
<h1 >bye </h1 >
)
}
function PageThree (){
const [data , setData ] = useState ([]);
useEffect (() => {
axios .get ('http://localhost:8080/react')
.then (response => {
setData (response .data );
})
.catch (error => {
console .log (error );
});
}, []);
let result = [];
for (let cafe of data ){
console .log ('카페', cafe )
result .push (
<li key ={cafe ._id }>
<ol >{cafe .name }</ol >
<ol >{cafe .repreMenu }</ol >
</li >
)
}
return (
<h1 >
{result }
</h1 >
)
}
function SetPage () {
const [pageNumber , setPage ] = useState (0 );
let content = null ;
switch (pageNumber ){
case 0 :
content = <PageOne ></PageOne >
break ;
case 1 :
content = <PageTwo ></PageTwo >
break ;
case 2 :
content = <PageThree ></PageThree >
break ;
}
return (
<div >
<button onClick ={() =>setPage (0 )}>
Click me
</button >
<button onClick ={() =>setPage (1 )}>
Click me
</button >
<button onClick ={() =>setPage (2 )}>
Click me
</button >
{content }
</div >
);
}
function App () {
return (
<div className ="App">
<SetPage ></SetPage >
</div >
);
}
export default App ;
이를 동시에 실행하며 확인하기 위해 서버는 8080주소로, 리액트 클라이언트는 3000번 서버로 실행하였다.
이제 버튼을 누르면 글자가 바뀌고 마지막 버튼을 누르면 생성 되어있는 카페의 정보들을 띄워준다. 게다가 Db의 변경 또한 반영된다(버튼을 누를 시)
생성되어있는 카페들
우선은 기존에 내가 만들었던 웹의 이미지이다. DB에 저장된 정보를 목록처럼 보여주고 있다.
아래는 위의 코드로 작성한 React화면이다. 세 개의 버튼을 누르면 각각 띄는 화면이 바뀐다.
버튼을 누르면 바뀌다가. 마지막 버튼을 누르면,
이처럼 Json형태로 넘겨받은 카페 목록을 보여준다.
그렇담 업데이트 역시 잘 반영할까? 서버측에서 db에 목록을 추가하면?
카페 C라는 목록을 추가하였다.
AXIOS가 잘 불러온다. 오늘은 뭔가 새로운 기술을 익히는 데 초점을 맞춘다는 느낌이라 개발 진도가 거의 안 나간 느낌이다. 그런데도 엄청난 시간을 잡아먹었다. 새벽 코딩이라니. 낭만일지도? 아무튼 이 글을 마무리 짓는 현재 시간 4시. 오늘의 개발 끝.
얼른 지금 하는 개발을 마무리짓고 지금 공부 중인 SQL을 적용한 간단한 사이트 역시 만들어보고 싶다. 그런데 현실은 제일 우선적으로 만들어야 할 것이 플러터 앱이라는 사실. 영 좋지 못하다.