2024.06.23 프로그래머스 - React Task Management 1
React 로 만드는 Task Management App 1
- Trello 같은 웹 사이트를 제작!
프로젝트 생성
- CRA 와 Vite중 Vite를 이용하여 프로젝트 생성
1
npm init vite
- framework : React
- variant : Typescript
- 위의 기술로 프로젝트 생성
- 생성 후 npm install로 의존성 설정
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"name": "react-task-app",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"typescript": "^5.2.2",
"vite": "^5.2.0"
}
}
프로젝트 구조 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
react-task-app
├─ src
│ ├─ App.css
│ ├─ App.tsx
│ ├─ components
│ │ ├─ ActionButton
│ │ │ ├─ ActionButton.css.ts
│ │ │ ├─ ActionButton.tsx
│ │ │ └─ DropdownForm
│ │ │ ├─ DropdownForm.css.ts
│ │ │ └─ DropdownForm.tsx
│ │ ├─ BoardList
│ │ │ ├─ BoardList.css.ts
│ │ │ ├─ BoardList.tsx
│ │ │ └─ SideForm
│ │ │ ├─ SideForm.css.ts
│ │ │ └─ SideForm.tsx
│ │ ├─ EditModal
│ │ │ ├─ EditModal.css.ts
│ │ │ └─ EditModal.tsx
│ │ ├─ List
│ │ │ ├─ List.css.ts
│ │ │ └─ List.tsx
│ │ ├─ ListsContainer
│ │ │ ├─ ListsContainer.css.ts
│ │ │ └─ ListsContainer.tsx
│ │ ├─ LoggerModal
│ │ │ ├─ LoggerModal.css.ts
│ │ │ ├─ LoggerModal.tsx
│ │ │ └─ LogItem
│ │ │ ├─ LogItem.css.ts
│ │ │ └─ LogItem.tsx
│ │ └─ Task
│ │ ├─ Task.css.ts
│ │ └─ Task.tsx
│ ├─ hooks
│ │ └─ redux.ts
│ ├─ index.css
│ ├─ main.tsx
│ ├─ store
│ │ ├─ index.ts
│ │ ├─ reducer
│ │ │ └─ reducer.ts
│ │ └─ slices
│ │ ├─ boardsSlice.ts
│ │ ├─ loggerSlice.ts
│ │ └─ modalSlice.ts
│ ├─ types
│ │ └─ index.ts
│ └─ vite-env.d.ts
├─ tsconfig.json
├─ tsconfig.node.json
└─ vite.config.ts
- src 내의 폴더 구조를 주목
components
- 재사용 가능한 컴포넌트를 저장하는 위치
hooks
- custom hook을 만들어 저장하는 위치
types
- 재사용하는 type들을 저장하는 위치
store
- Redux 의 소스를 저장하는 위치
이렇게 컴포넌트들을 미리 생성한다는 생각도 못했고, 이렇게 미리 쪼개놓은 상태로 시작하면 효율적일 것도 몰랐다. components 안에서 역할별 폴더를 또 따로 만들어서 세부적으로 또 나누어 놓는 방법 너무 유용하다.
프로젝트 의존성 설치
전역 상태 관리를 위한 라이브러리
- Redux + Redux Toolkit
동적 className을 위한 라이브러리
- clsx
CSS 를 위한 라이브러리
- vanila-extract-css
- utils
- vite-plugin
기타 라이브러리
- react-icons
- uuid
- react-beautiful-dnd
설치후 package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"dependencies": {
"@reduxjs/toolkit": "^2.2.5",
"@vanilla-extract/css": "^1.15.3",
"@vanilla-extract/css-utils": "^0.1.4",
"@vanilla-extract/vite-plugin": "^4.0.11",
"react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "^18.2.0",
"react-icons": "^5.2.1",
"redux": "^5.0.1",
"uuid": "^10.0.0"
},
"devDependencies": {
"@types/react": "^18.2.66",
"@types/react-dom": "^18.2.22",
"@typescript-eslint/eslint-plugin": "^7.2.0",
"@typescript-eslint/parser": "^7.2.0",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.6",
"typescript": "^5.2.2",
"vite": "^5.2.0"
}
}
Redux 준비
- Redux는
상태를 관리 하는
라이브러리 - 기본 state, props로도 상태 관리는 가능하나, 앱이 커지면 관리가 힘들어지고 소스가 지저분해진다.
- 이를 효율적으로 관리하기 위해 Redux 와 같은 전역적인 상태 관리가 가능한 라이브러리를 사용
Redux의 흐름
- Action = 객체, Dispatch = 함수 ⇒ Reducer = 함수
- Reducer의
type
에 따라 Redux Store에 있는 State에 업데이트를 한다. - React Component 가 리 렌더링 된다.
Redux store 생성
- 각 상태를 사용할 Slice 생성 (createSlice)
- 생성 한 slice의 reducer를 하나의 reducer로 생성 후 export (slice.reducer)
- configureStore를 통해 하나로 모은 reducer를 store의 reducer 객체로 할당 후 export default
- main.tsx에서 react-redux 라이브러리의 Provider를 통해 전역 상태 설정 및 store 변수 할당
세부 redux 설정은 github 참고
- https://github.com/ykdman/Programmers-DevCourse/tree/main/react-task-app
전역 스타일 생성하기
- vanila-extract/css 를 이용하여 전역적인 :root 에 대한 스타일링과, 각 요소별 스타일링 설정
App.css.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
// App 전역 스타일링 import { createGlobalTheme, style } from "@vanilla-extract/css"; export const vars = createGlobalTheme(":root", { color: { main: "#ffa726", mainDarker: "#f57c00", mainFaded: "#ffb74d", mainFadedBright: "#ffb75a6", list: "rgb(235,236,240)", task: "rgb(255,255,255)", taskHover: "rgb(245,245,245)", brightText: "rgv(255,255,255)", darkText: "rgb(24,42,77)", secondaryDarkText: "rgb(94,108,132)", secondaryDarkTextHover: "rgb(218,219,226)", selectedTab: "rgb(137,176,174)", updateButton: "rgb(237,180,88)", deleteButton: "rgb(237,51,88)", }, fontSizing: { T1: "32px", T2: "24px", T3: "18px", T4: "14px", P1: "12px", }, spacing: { small: "5px", medium: "10px", big1: "20px", big2: "15px", listSpacing: "30px", }, font: { body: "arial", }, shadow: { basic: "4px 4px 8px 0px rgba(34,60,80, 0.2)", }, minWidth: { list: "250px", }, }); export const appContainer = style({ display: "flex", flexDirection: "column", minHeight: "100vh", height: "max-content", width: "100vw", }); export const board = style({ display: "flex", flexDirection: "row", height: "100%", }); export const buttons = style({ marginTop: "auto", padding: vars.spacing.big2, });
App.tsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import { appContainer, board, buttons } from "./App.css.ts"; import reactLogo from "./assets/react.svg"; function App() { return ( <div className={appContainer}> <div className={board}></div> <div> <button className={buttons}>이 게시판 삭제하기</button> <button></button> </div> </div> ); } export default App;
오늘 느낀점
Redux를 이전에 한 번 공부해보긴 했는데, 생각보다 사용법이 훨씬 복잡하고, 신경써줘야 할 부분이 많았다.
일단 Redux 공식 문서를 통해서 RTK (Redux-Toolkit) 과 Redux의 원리 및 사용법을 이해하고 또한 이것이 다른 라이브러리로는 어떻게 대체될 수 있는지에 대해 고민하는 시간이 필요할 것 같다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.