[#1] React로 Task Manager 만들기

오닐·2022년 5월 22일
0

React : Task Manager

목록 보기
1/11

🐰0. 들어가기 전에

전에 자바스크립트로 대시보드 느낌의 태스크 매니저를 만들었었다. 원래는 포트폴리오를 준비하면서 리팩토링할 생각이었는데, 리액트를 배우던 어느 날 '어라, 이거 너무 리액트용 프로젝트 아니냐?' 하는 생각이 들었다.

멋모르던 시절에 그냥 html 페이지 여러 개로 만들다 보니 header나 side-bar처럼 중복되는 코드가 많았고 그 외에도 같은 기능을 하는 코드들이 많았다. 이걸 단순히 줄이는 것보다는 Component화 해서 SPA로 깔끔하게 새로 만드는 게 낫지 않을까 싶었고, 일단 한 번 해보려고 한다.


🐰1. 개선하고 싶은 사항

  • Bootstrap 대신 Styled-components로 CSS 디자인
  • jQuery 대신 ES6 문법 사용
  • 트래커와 위시리스트 다시 도전!
  • API 연습 겸 시계 또는 날씨 위젯 구현
  • 다이어리 수정 및 내용 확인 페이지 연동
  • MERN 스택 도... 도전!

지난 번과 마찬가지로 아마 100퍼센트 다 구현하지는 못할 테지만, 아는 지식 모르는 지식 총동원해서 만들어 보자고. 이거 하나로 포트폴리오 끝내 보자고.


🐰2. 폴더 구조


초기 폴더 구조는 이렇게 짰다. 공부할 겸 설명해 보자면

  • Node_modules: 설치한 라이브러리 보관함
  • Public: Virtual DOM을 사용할 때 필요한 Static 파일 보관함
  • src: 소스 코드 보관함
    • components: 따로 분리한 컴포넌트 보관함
    • pages: Home, Diary 등 프로젝트의 페이지 보관함
    • util: 자주 쓰이는 함수 보관함
  • App.css: App 파일에 적용되는 css 파일
  • App.js: 메인 페이지에 들어갈 HTML을 구성하는 파일
  • index.css: index 파일에 적용되는 css 파일
  • index.js: 프로젝트를 열었을 때 가장 먼저 실행되는, 첫 페이지에서 마주하는 코드 파일
  • Package.json: 설치한 라이브러리에 대한 정보(ex.버전) 보관함

이 외에 필요한 파일이나 폴더는 차차 추가할 생각이다.


🐰3. 초기 설정

  • React Router 설치
    npm install react-router-dom@6
  • Styled-components 설치
    npm install --save styled-components
  • React-icons 설치
    npm install react-icons --save

다른 라이브러리들은 필요할 때마다 추가할 예정이다.


🐰4. Router로 페이지 나누기

라우팅(Routing)이란, 어떤 네트워크 내에서 데이터를 내보낼 경로를 행위 자체와 일련의 과정을 포함한 말이다. 여기에 우리가 아는 페이지의 개념을 덧붙인 페이지 라우팅(Page Routing)은 말 그대로 웹 서버가 요청에 알맞은 페이지를 선택하고 이를 사용자에게 반환하는 것을 말한다.
리액트는 SPA(Single Page Application)의 일종이기 때문에 React-router라는 라이브러리를 이용해서 라우팅함으로써 여러 페이지를 띄워주는 것처럼 보여줄 수 있다.

사용방법은 아주 쉽다. 먼저 React-router 라이브러리를 설치한 후, App.js 파일에 BrowserRouter와 Route, Routes를 import한다. 그리고 라우팅하고자 하는 요소를 <BrowserRouter>로 감싼다.
<BrowserRouter> 내부에 페이자 역할을 할 요소들을 <Routes>로 감싸고, 하나의 페이지 역할을 할 요소의 경로를 <Route path='url경로' element={컴포넌트}>에 전달하면 끝.


🐰5. 기본 컴포넌트 만들기

5-1. Header

페이지를 라우팅한 뒤에는 우선 모든 페이지에서 사용할 가장 기본 컴포넌트들부터 만들어 주었다. JS 프로젝트 때 헤더와 사이드바는 모든 페이지에 다 존재했었기 때문에 별다른 구상 없이 바로 만들 수 있었다.

JS 프로젝트와 달리 리액트로 만들면서 Styled-components 라이브러리로 CSS를 디자인했다. CSS 파일을 import해서 사용하면 CSS가 적용되는 범위가 제한되어 있지 않기 때문에 스타일이 전역에 적용되게 된다. 그러면 직접적으로 CSS 파일을 import하지 않은 다른 컴포넌트에도 스타일이 적용될 수 있기 때문에, 특정 스타일이 설정된 컴포넌트를 구축할 수 있도록 도와주는 라이브러리를 사용했다.

이렇게 하는 게 맞나?
먼저 가장 상위 div(StyledHeader)에만 적용했다가 코드가 너무 길어져서 나름대로 분리해 보았다.


header 태그에 flex와 space-between을 적용해서 내용물을 양 사이드 공백 없이 배치했다. div 대신 header를 사용한 것 외에 특별한 점은 없다.


header 태그 내부에서 input과 :focus가 중첩된 부분을 따로 분리했다. styled-components에서는 &자를 사용하면 자기 자신을 선택할 수 있다.


사이드바를 열 수 있는 토글 버튼도 미디어 쿼리 사용을 위해 분리했다. 브라우저 너비가 768px보다 작을 때는 버튼을 보여주고 768px보다 클 때는 감추기 위해 display: none(block) 속성을 사용했다. visibility: hidden(visible) 속성과 다른 점은, 전자는 모습뿐만 아니라 요소가 차지하던 자리도 사라지는 것이고 후자는 요소가 자리는 그대로 차지하되 모습만 감추는 것이다. 나는 토글 버튼이 보이지 않을 때 그 자리를 비워두고 싶지 않았기 때문에 display 속성을 적용했다.


5-2. Dropdown

Dropdown은 이 글을 참고해서 만들었다. 이 전에는 부트스트랩에서 제공하는 드롭다운을 그대로 가져다 썼기 때문에 이번에는 CSS로 직접 구현하고 싶었다.

우선 일반 HTML 짜듯 레이아웃을 설정하고, 드롭다운 활성화 여부를 state에 저장했다. 클릭했을 때 리스트가 나와야 하므로 기본값은 false를 주었고, 이 state를 변경하는 함수(activeHandler)를 만들었다.

일전에 바닐라 JS로 토글을 구현할 때는 classList.toggle 메서드를 쓰면 그만이었지만, 이번에는 not 연산자를 사용해서 그 효과를 내주었다. 공부를 하면 할 수록 not 연산자가 쓰이는 곳이 많다는 걸 새삼 느낀다.

button을 클릭하면 activeHandler 함수를 따라 isActive가 true와 false를 넘나든다. 이때 state 값이 true이면 <Nav> 태그에 active가, false이면 inactive가 props로 전달되도록 삼항 연산자를 이용해서 조건을 부여했다.

styled-components를 이용해서 Nav에 미리 스타일을 설정해두었다. display: none으로 감추어져 있던 nav에 active라는 props가 전달되면 display: block으로 바뀌어서 nav 목록이 뿅 하고 나타난다.

nav 목록에는 useNavigate를 이용해서 링크를 걸어주었다.


5-3. SideBar

이전 프로젝트와 마찬가지로 화면이 충분히 클 때는 왼쪽에 고정, 화면 사이즈가 작을 때는 사이드바 오픈 버튼만 남기고 닫혀 있게끔 만들어 주었다.

고정되어 있지 않을 때는 사용자가 필요에 따라 사이드바를 열고 닫을 수 있도록 열림 버튼과 닫힘 버튼을 만들었다.

우선 Dropdown과 마찬가지로 state를 만들어서 isVisible의 true/false 여부를 저장했고, 이를 sidebarToggler라는 함수를 만들어서 변경할 수 있게끔 했다. 그리고 이 함수를 (짤에서는 너무 빨리 지나가서 잘 안 보이는) 닫힘 버튼에 onClick 이벤트와 연결시켰다.

여기까지는 한 컴포넌트 내에서 이루어지는 동작이라 어려울 것이 없었지만, 문제는 열림 버튼이다. 닫혀 있는 사이드바를 열어야 하기 때문에 사이드바 아닌 헤더에 만들다 보니 이 둘을 연결시켜야 하기 때문이다. 바닐라 JS로 만들었을 때는 같은 페이지에 있는 요소라 DOM을 사용해서 쉽게 구현할 수 있었는데 이번에는 조금 복잡해서 잠시 미뤄두었다. 강의에서 배운 바에 의하면 둘의 공통 부모 컴포넌트인 App에 state를 끌어올렸다가 내려주는 방식으로 가능할 것 같은데, 우선은 다른 쉬운 것부터 해결하고 돌아와서 완성시켜야겠다.


🐰6. 가벼운 회고

한 번 만들어 봤던 걸 다시 만드는 작업이지만, 프레임워크가 달라지고 CSS 스타일도 달라져서 그런지 지루하지 않고 재미있다! 새로운 기술을 적용하느라 조금 생소하고 어렵기는 해도 확실히 눈에 바로바로 보이는 무언가를 만들 때가 가장 재미있는 것 같다.
아직 옛 버릇을 못 버려서 코드를 짜는 동시에 수정하려고 하느라 시간이 좀 오래 걸리는 것만 빼면 순조로운 것 같다.
일단 깃허브에 올려두고 열심히 만들고 열심히 다듬어 봐야겠다. JS 프로젝트에 비해 얼마나 발전된 결과물이 나올지 벌써부터 기대된다!

0개의 댓글