요구사항 정의
구현해야 할 기능
- Create Todo
- Read Todos, Todo
- Update Todo
- Delete Todo
요구사항
[공통]
- todos 데이터는 리덕스를 사용해 전역으로 상태 관리
- todos 모듈은 Ducks 패턴으로 구현
[메인 페이지]
- 디자인과 화면 구성은 자유롭게 구현
- Todo의 상태에 '완료' 그룹과 '진행 중' 그룹을 나뉘어서 보이도록 구현
- Todo 추가 시 제목 input과 내용 input은 다시 빈 값이 되도록 구현
- input에 값이 있는 상태에서 상세페이지로 이동하는 경우, input의 value 초기화
- Todo의 완료상태가 true면 상태 버튼의 라벨을 취소, false면 라벨을 완료로 보이도록 구현
- Layout 최대 넓이는 1200px, 최소 넓이는 800px로 제한하고, 전체 화면의 가운데로 정렬
- 상세 보기 클릭 시 Todo의 상세 페이지로 이동
[상세 페이지]
상세 페이지의 디자인과 화면 구성은 자유롭게 구성하되, 아래 요소들은 보여야 함
- Todo의 ID
- Todo의 제목
- Todo의 내용
- 이전으로 버튼 : 클릭 시 리스트 화면으로 되돌아 감
[제한 사항]
- map 사용 시 반드시 key를 넣어야 하며, map의 index 사용 금지
- Todo의 id 생성 시 todos.length를 사용해 생성하면 안 됨
컴포넌트 분리 및 폴더 구조
📦src
┣ 📂components
┃ ┗ 📜Main.jsx : 메인 페이지
┃ ┣ 📜Header.jsx : 헤더 컴포넌트
┃ ┣ 📜Form.jsx : todo를 입력하는 Form 섹션 컴포넌트
┃ ┣ 📜ListWorking.jsx : Working 섹션 컴포넌트
┃ ┣ 📜ListDone.jsx : Done 섹션 컴포넌트
┃ ┣ 📜ListMap.jsx : Working, Done을 처리하고 박스를 보여주는 컴포넌트
┃ ┣ 📜DetailPage.jsx : 상세페이지 컴포넌트
┃ ┣ 📜GlobalStyle.jsx : styled-Components 글로벌 스타일 분류
┣ 📂redux
┃ ┣ 📂config
┃ ┃ ┗ 📜configStore.js
┃ ┗ 📂modules
┃ ┃ ┗ 📜todos.js
┣ 📂shared
┃ ┗ 📜Router.js
┣ 📜App.jsx : App.jsx → Main.jsx로 라우터 처리
┣ 📜index.js
┗ 📜reportWebVitals.js
리액트 useState로 투두리스트 만들기 때와 요구사항이 비슷해 컴포넌트 분리 자체는 크게 달라진 부분이 없다. 스타일드 컴포넌트나 라우팅 관련 파일들만 추가되었다.
중점을 둔 사항
1. 전역 처리해야 할 데이터, 부분적으로 필요한 데이터 구분
// Form.jsx
// useState
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
...
// 추가하기 버튼 onClick
const onAddBtnClick = (e) => {
e.preventDefault();
if(title === '' || body === '') {
alert('투 두 리스트를 입력해주세요.');
return;
}
const newTodo = {
id: nanoid(),
title,
body,
isDone: false,
};
dispatch(addTodo(newTodo));
setTitle('');
setBody('');
};
to do 입력 form 내부에서만 사용하는 title, body값은 검증 후 넣어줘야 하는 값이고 (빈 값이면 등록되지 않도록) 최종적으로 넣어야 하는 데이터는 title, body뿐만이 아니라 id, isDone 값이 붙은 객체 데이터가 들어가야 하기 때문에 전역처리를 하지 않고 useState로 처리했다.
반면 id, title, body, isDone값이 모두 들어간 하나의 투 두 리스트는 여러 컴포넌트에서 사용해야 하므로 리덕스를 사용해 전역처리를 해주었다.
2. 리덕스 흐름 이해하기
프롭스 드릴링 현상을 막기 위해 전역 처리를 해야 할 필요가 있고, 이를 위해 리덕스를 사용한다는 것까지는 충분히 이해했다. 하지만 그걸 코드로 직접 구현해 본다는 건 다른 영역이었다. 리덕스의 흐름에 따른 코드 구현이 이해가지 않아 제공되는 리덕스 강의를 두 번 듣고 예시 코드와 함께 흐름을 적어보면서 차근차근 정리했다. useContext가 있는데 왜 리덕스를 쓰는지, 리덕스는 데이터를 어떻게 만들고 흘려보내는지.. 투 두 리스트를 구현할 정도로는 이해가 되었지만 툭 치면 바로 뱉어낼 수 있을 정도는 아니라 꼭 추가 공부를 해야 한다!
https://github.com/hansololiviakim/react-intermediate/tree/main/5_redux-to-do-list
질의사항
기술매니저님과의 질의
❓ 라우팅을 사용할 경우 지금과 같이 App.jsx에서 Main.jsx라는 파일을 추가로 만들어 넘겨줘야 하는지 궁금하다.
💡 App.jsx에 브라우저 라우터를 아예 한 번에 걸어서 넣어도 된다. 또한 router.js를 router.jsx로 바꿔주는 게 좋고 router.js를 지금의 App.jsx에 아예 걸어주면 좋다.
❓ 스타일드 컴포넌트를 올바르게 사용했는지 궁금하다. 오히려 스타일드 컴포넌트를 사용했을 때 가독성이 떨어져 보이는데 이렇게 적는 게 맞는지?
💡 글로벌 스타일은 App.jsx에 바로 넣어주면 된다. 현업에서는 tailwind를 주로 쓰고 부족한 부분은 스타일드 컴포넌트를 같이 사용하는 방식으로 진행한다.
❓ modules/todo.js에서 TOGGLE_STATUS_TODO에서 isDone값을 바꿀 때 map을 돌려 스프레드 연산자로 복사한 값을 바꿔주는 방식을 사용했는데 이 방식이 맞는지, 더 효율적인 방법이 있는지 궁금하다.
💡 어차피 갈아 끼우는 로직은 어딘가에는 들어가야 하기 때문에 더 효율적 이기라기보단 조금 더 알아보기 쉽게 정리하는 정도까지가 전부일 것 같다.
❓ 코드에 수정하면 좋을 부분이 있으면 알고 싶다.
💡 지금은 컴포넌트마다 각각 해당하는 로직이 들어가 있는데 로직 관리는 되도록 한 파일에서 하고, props로 내려주는 게 더 좋다. 즉, 최상위 컴포넌트에서 로직을 구현하고 값만 내려야 한다. depth가 깊어지면 각각 부르는 게 맞긴 하는데 지금과 같이 몇 개 없는 상황에서는 상위에서 내려주는 게 더 좋다.
✅ 리덕스를 쓴다는 게 결국 바닐라 자바스크립트에서 전역변수를 사용하는 개념과 비슷한 건지 궁금해서 찾아보았는데, 그런 비유는 일부분 맞을 수 있지만 좀 더 정확하게는 리덕스는 중앙 집중화된 상태 관리 도구라고 한다. 중앙 집중화된 상태 관리를 통해 애플리케이션의 모든 상태를 한 곳에서 관리하고, 필요한 컴포넌트에서 상태를 가져와 사용하는 것! 조금 더 생각해 보니 바닐라 자바스크립트는 대부분 MPA 방식이고 리액트는 SPA 방식이기 때문에 비슷한 의미를 가지지만 리액트는 전역 상태 관리를 위한 도구라고 분리해서 이해하는 게 더 좋을 듯하다.
리덕스의 보일러 플레이트를 줄인 리코일에 대해서는 이름을 들어본 적 있어 이번 주에 리덕스와 리코일을 비교해보려 했는데 아직 리덕스에 대한 이해가 확실하지 않은 상태라서.. 리덕스 흐름을 더 공부한 뒤에 리코일과 비교해보려고 한다. 어렵다.. 그리고 재밌다!
'Diary > Retrospective' 카테고리의 다른 글
[항해99 / TIL] 🚢 23-05-03 리액트 query, axios로 게시판 만들기 (4) | 2023.05.03 |
---|---|
[항해99 / TIL] 🚢 23-04-29 Styled Components로 화면 요소 만들기 (0) | 2023.04.29 |
[항해99 / TIL] 🚢 23-04-17 리액트 useState로 투두리스트 만들기 (2) | 2023.04.17 |
[항해99 / TIL] 🚢 23-04-15 chatGPT에게 리액트 기초 물어보기 (2) | 2023.04.16 |
[항해99 / 온보딩주차] 🔎 풀스택 미니 프로젝트 회고 (0) | 2023.04.06 |