학습했던 React 기초를 활용하여 Task 정리 앱을 만들어보자.
주로 리액트, 리덕스, 타입스크립트 와 추가 라이브러리를 이용한다.
npx create-react-app ./path
npm과 npx의 차이는 다음과 같다.
npm : npm 레지스트리에 많은 패키지들이 들어있는데, 그 패키지를 가져와서 node_modules 폴더에 설치해주는 역할.
npx : 패키지를 가져오고 설치한 후에 node_moudles에 저장을 하지 않고 설치를 수행. (한번만 수행할 때는 npx 이용)
위 방법도 있지만, 다른 방법도 있다.
npm init vite
npm을 이용하여 node_modules 폴더에 설치를 수행한다.
Project name 을 현재 폴더의 이름으로 설정하려면 ./을 입력하고,
프레임워크는 React를 선택한다.
언어는 TypeScript를 선택한다.
이제 폴더에 React가 생성된 것을 확인할 수 있다.
이제 npm i 를 통하여 package의 라이브러리들을 설치한다.
이후에, npm run dev 명령어를 통해 프로그램을 실행한다.
이 화면은 src > App.tsx 파일에서 동작을 확인할 수 있고, index.html에서 html 구조를 확인할 수 있다.
이제, src 폴더에 다음의 폴더들을 생성해보자.
components, hooks, store . types
이 폴더들은, Redux를 사용할 때 위처럼 폴더를 나누어 관리한다.
components : 생성한 컴포넌트들을 보관한다.
hooks : 커스텀 hooks를 만들어 보관한다.
store : 부모 컴포넌트와 자식 컴포넌트와 소통하려면 props를 이용한다. 이 props가 많아질 때, 소스코드가 지저분해지고, 관리하기 어려워지기 때문에 상태관리 라이브러리를 사용한다. 대표적으로 Redux가 있고, Mobx, Zustand, Recoil, React Context 등이 있다. 이번 학습에서는 Redux를 이용할건데, Redux의 소스코드를 store에 넣어서 사용한다.
types : 코드에서 사용하는 type들을 모아놓는다. 해당 type을export 하여 사용한다.
먼저 hooks 폴더에 redux.ts 파일을 생성하여 Redux를 위해 필요한 hooks들을 작성할 것이다.
useSelector , useDispatch 등을 만들어 사용한다.
store 폴더에는 index.ts 파일을 생성하여, Redux를 사용할 때 Redux 스토어를 만들어야 하는데 여기서 생성한다.
또한, store > reducer , store > slices 의 폴더를 생성한다.
redux toolkit을 이용할 때 slice를 만들어서 사용한다.
예를 들어, 태스크 정리 앱에서는, Board, Modal 의 각각 슬라이스가 존재할 것이다. 따라서, 다음의 파일을 생성한다. boardsSlice.ts , loggerSlice.ts , modalSlice.ts
reducer 에는 reducer.ts 파일을 생성한다.
정리해보자면, slices(객체)에는 reducer가 들어있는데, reducer를 reducer.ts에서 통합한 후, reducer를 이용해서 store를 만든다.
types에는 index.ts 파일을 생성한다.
여기에 타입들을 명시한다.
components에는 다음의 폴더를 생성한다.
BoardList (게시물 버튼), ListsContainer (할 일 목록이 들어갈 영역) , LoggerModal(로그 모달) , ModalEdit (수정 모달) , ActionButton (새로운 일 등록 클릭시 텍스트박스) , List (리스트들) , Task (Task 하나하나)
ActionButton의 경우에는 클릭 했을 때의 영역을 DropDownForm이 필요하므로, DropDownForm 폴더를 생성한다.
새로운 일 등록 클릭 버튼을 위해 ActionButton에 ActionButton.tsx 파일을 생성한다.
같은 위치에 ActionButton.tsx의 스타일을 위한,
ActionButton.css.ts 파일을 생성한다.
이제 rafce로 각 .tsx파일의 기본 틀을 생성해준다.
모든 폴더에 마찬가지로 css.ts 파일과 .tsx파일을 생성해준다.
BoardList에는 텍스트박스를 위한 폴더(SideForm)를 추가한다.
또한, LoggerModal에는 사용자 활동기록을 표시하므로, 각 항목을 의미하는 LogItem 폴더를 추가한다.
이제 ,앱을 만들 때 필요한 패키지들을 설치해보자.
@reduxjs/toolkit redux clsx @vanilla-extract/css @vanilla-extract/css-utils
@vanilla-extract/vite-plugin react-icons uuid react-beautiful-dnd
여기서 clsx는, <div className> 을 동적으로 설정가능하다.
예시는 다음과 같다.
<div className = {clsx('foo', true && 'bar', 'baz')}>DropDownForm</div>
/* 위코드는 아래 코드와 동일한 결과를 갖는다.*/
<div className = {'foo bar baz'}>DropDownForm</div>
vanilla-extract는 typescript에서 css를 작성하기 위한 패키지이다.
react-beautiful-dnd 는 drag and drop 기능을 위한 패키지이다.
이제 npm install @~~를 통해 모든 패키지들을 설치해주자.
설치가 성공적으로 끝났으면, package의 dependencies에서 설치패키지들을 확인할 수 있다.
Redux는 상태를 관리하는 라이브러리이다.
따라서, 써도되고 안써도 되는 선택사항이다.
Redux를 사용하지 않으면, State와 Props를 이용해서 여러 컴포넌트와 공유할 수 있다.
하지만, 앱이 커지면 복잡해지고 유지보수가 힘들 수 있다. 따라서, 이를 해결하기 위해 Redux를 사용한다.
Redux의 flow는 다음과 같다.
1. Action Dispatch : 액션(객체) 전달(함수) -> Reducer(함수)로.
Reducer는 type에 따라 return을 하는 값이 Redux Store에 있는 State에 업데이트된다. 이 후에, React Component가 리렌더링 된다.
Action 객체 Dispatch 함수 => Reducer 함수 type return => Redux Store State => React Componet
이 구조를 uni directional 하다고 한다.
팁 :
ES7+ React/Redux/React-Native snippets 익스텐션 설치 후,
.tsx 파일에서 rafce (스니펫) 를 입력하면, 기본적인 함수형 컴포넌트 틀이 자동완성 된다.
export default 이름 과 export const 이름의 차이는, export default는 경로만 맞으면 import의 이름이 자유로운 반면, export는 import할 때 이름까지 같아야한다.