Cookie Project 2
LeeMir, 08 February 2021
Bulletin Board with React
리액트를 이용해 게시판(CRUD) 구현해보기
2021.02.05 ~ 2021.02.07
https://github.com/LeeMir/react-cookie-board
작년 말부터 학과 동기끼리 웹 프로젝트를 하기로 해서 나는 프론트엔드 개발자로 참여하게 되었다.
그에 앞서, 내가 아는 것이 부족하므로 개인용 쿠키 프로젝트로 게시판 컨텐츠를 만들게 되었다.
사용한 기술 스택이나 로직은 위 링크에 해당하는 레포에 README로 올려놓았고, 하면서 느낀 점 위주로 글을 작성해볼까 한다.
거의 사흘에 걸쳐서 만들었는데, 리액트로 무언가를 만드는 것은 처음이라 깔끔하게 작성하지는 못했다. 여러가지 참고 자료들이 도움이 되었다.
처음에는 DB, 백엔드 없이 프론트엔드에서 받아온 “척”만 해서 프론트엔드로만 개발하려고 했는데, 글을 작성하는 것에서 막혀서 프론트엔드에서 파일 입출력하는 해괴한 방법을 찾아보다가 결국 백엔드도 만들긴 해야겠다싶어 백엔드까지 구축하게 됐다.
그 와중에 백엔드도 처음이라 간단한 API 구성하는 것도 좀 걸렸다. 나중에 코드 리뷰를 하면서 알게 된 사실로, 나는 처음에 create-react-app
으로 만든 다음에 Frontend 폴더와 Backend 폴더를 만들어서 이것저것 다시 다 옮기는 데 오래 걸렸는데, 그냥 처음부터 프로젝트 폴더 안에 폴더를 나누고 Frontend 폴더에서 create-react-app
을 해야한다고 한다. 그리고 이것을 깃허브에 연동하려고 하는데, 최상위에 있는 node_modules는 기본적으로 감지 안되게 되어있으나 frontend와 backend 폴더에 생긴 node_modules는 감지 안되게 하는 방법을 몰라 5k개가 넘는 요소들이 변경 사항에 떠 매우 당황했었다. 답은 .gitignore
였다..
스타일의 경우 styled component
를 사용하면 더 편해보였으나, 팀 프로젝트에 material-ui
와 scss
를 쓰기로 해서 적응을 위해 이번 쿠키 프로젝트에서도 사용했다. 확실히 scss
는 css
를 쓸 줄 아니까 쓰기 편했는데, material-ui
는 많이 생소해서 해당 공식 문서를 계속 켜놓고 봤다.
나는 하나도 모르니까 최대한 다양한 것을 다 써보자라는 컨셉으로 쿠키 프로젝트를 진행했다.
백엔드는 Node.js의 Express를 사용했고, 모두 app.use
를 사용해서 API를 구성했다. 특별한 이유가 있기 보다는 백엔드 공부보다 프론트엔드가 일단 먼저라고 생각해서 백엔드를 최대한 간단하고 편하게 만들었다.
프론트엔드에서 백엔드와 통신할 때는 fetch()
를 썼고, async - await
문법으로 비동기 처리도 해보았다(코드 리뷰 때 알게 된 사실로 fetch().then
을 써서 쓸모가 없었다..). 찾아보니까 사람들은 fetch()
보다 axios
를 많이 쓰는 것 같아 다음 쿠키 프로젝트할 기회가 있다면 axios
를 사용해볼 생각이다.
DB는 “게시판”을 만드는 거니까 필요한 정보가 글에 대한 정보와 사람에 대한 정보라고 생각했는데, 사람에 대한 정보 즉, 로그인까지 구현하게 되면 프로젝트에서 배보다 배꼽이 커지는 느낌이 들어서 과감하게 배제했고 글에 대한 정보만 DB로 구축하기로 했다. 글에 대한 정보라고 함은, [글의 id(key 역할), 제목, 저자, 내용]에서 끝날 것 같아서 json
파일을 DB로 사용하는 방식인 LowDB
를 사용하기로 했다. 이 역시 로그인과 마찬가지로, MongoDB나 Mysql을 사용하면 DB 구축이 프로젝트의 중심이 될 것 같아 내린 결정이다.
단, LowDB
는 자동으로 id를 만들고 관리해주지 않아서 shortid
라는 난수id를 생성해주는 라이브러리를 사용해야한다고 한다. 처음에는 내가 id를 생성하고 관리하는 알고리즘을 생각했는데, 글 개수로 id를 정의해보려다가 중간에 있는 글이 삭제되면 어떻게 해야할 지 감이 오질 않아서 나도 결국 shortid
를 사용했다. 그런데 이 부분의 경우 큰 프로젝트에서는 다른 DB를 사용하면 해결되므로 크게 신경쓰지 않았다.
프론트엔드를 공부하기 위한 프로젝트이니만큼, 백엔드가 굉장히 간단하고 빠르게 구축이 완료되어서 더 손보거나 할 게 없어 프로젝트 폴더에서 백엔드 따로, 프론트엔드 따로 npm start
할 필요 없이 npm-run-all
을 이용해서 최상위에서 npm start
한번만 입력해도 백과 프론트가 동시에 실행되게 하고 프론트만 종일 개발했다.
가장 처음에 만든 기능은 CRUD 중 R(조회)이었다. 하나를 자세히 보여주는 R이 아니라 전체 글을 받아서 map
을 이용해 출력하는 List 컴포넌트를 만들었다. 한 글을 자세히 보여주는 것부터 하면 조금 더 편했을지도 모르는데, 처음부터 이게 되는지도 모르고 map
을 쓰니까 오류가 엄청 많이 났었다. 그것을 고치는 데에도 한세월이 걸렸는데, 그렇게 한세월하면서 어느정도 감이 잡히니까 글 하나를 자세히 보여주는 것은 금방했다.
그 다음 만든 기능은 C(생성/글쓰기)였다. 막막했던 점은 바닐라js에서는 document.getElementById()
를 써서 input value를 받아왔었는데, React에서는 setState
로 상태관리를 해줘야 input value를 받아서 이것을 서버로 보낼 수 있었다. 나중에 U(수정)를 만들 때 C에 사용한 코드를 복사해 만들면서 서버로부터 기존에 있던 글 정보를 받아 input에 value로 미리 집어넣으려고 했는데, TextField에 value 컴포넌트를 넣는 순간 제어를 할 수 없게 돼 입력을 해도 값이 변하지를 않아 또 하나의 벽에 부딪혔다. 이것을 setState
와 componentDidMount()
로 해결해보려했는데 잘 되지 않아 한참을 방황하다가, 결국 React-Hooks
의 useState()
와 useEffect()
로 구현하니까 해결이 되었다.
D는 서버로 글의 id만 넘기면 서버에서 DB 접근해 삭제하면 돼서 크게 어렵지 않았다. 다만 fetch().then
에서 사이트를 List로 이동하게 했는데, 그 부분이 작동하지 않아 이유를 고민해보니 서버에서 데이터 삭제만 하고 응답이 오질 않아서 .then
이 실행되지 않은 것이라고 판단해 쓸모 없지만 글의 id를 프론트로 응답하게 하니까 .then
이 잘 작동하였다.
확실히 이렇게 개인 쿠키 프로젝트를 하나 하고나면 그 언어뿐만 아니라 프로젝트는 어떻게 진행되는지 처음부터 끝까지 구석구석을 해볼 수 있어서 좋은 것 같다. 다만 그것을 사흘에 욱여넣느라 조금 힘들었다.
그리고 진행중인 팀 프로젝트는 타입스크립트를 사용하기 때문에 만약 쿠키 프로젝트를 하나 더 할 시간이 있다면 타입스크립트 중심으로 해볼 생각이다!