🐈오늘 공부한 것
✔️Props drilling 과제
오늘은 리덕스를 공부하기 전에 hooks 로 상태를 관리하며 기능을 구현하는 과제를 했다. 장바구니 과제였는데, 처음에 컴포넌트 구조를 파악하고 state를 어떻게 props 로 내려줄지 생각하는 부분이 살짝 어려웠다.
알아보기 힘들긴 하지만... 간단하게 이런 식으로 도식화(?) 를 해봤는데 다시 리뷰를 해보자면... 먼저 App.js 안에 ItemsListContainer 컴포넌트와 ShoppingCart 컴포넌트가 존재한다. 이 최상단 컴포넌트 안에서 items와 cartItems 라는 상태를 관리하고 있는데, 상태와 상태 변경 함수를 각각의 컴포넌트에 props 로 내려주어 상태 끌어올리기로 변경시켜주어야 함.
요구사항은 크게 3가지가 있었는데
1. Items컨테이너에서 Item 클릭시, 해당 Item이 ShoppingCart 컴포넌트에 보여져야함.
2. ShoppingCart 컴포넌트에서 아이템 수량을 수정할 수 있어야 함.
3. ShoppingCart 에서 삭제 버튼을 누르면 장바구니에 담긴 아이템 삭제.
핵심은 cartItems 상태를 통해 보여지는 값을 관리하고 수량을 변경하고 삭제하는 것이었다. 먼저 1번 요구사항을 해결하기 위해서 ItemListContainer 에 cartItems 상태와 그 함수를 내려주고, handleClick 으로 그 하위 컴포넌트에서 받아오는 id 값으로 조회하여 cartItems에 해당 item이 존재하는지 확인 후 경우에 맞게 분기시켜 item 추가 || item 수량 추가를 해주었다. 레퍼런스 코드에서는 item 수량 추가 함수를 App컴포넌트에서 미리 정의해 내려주는 방식으로 사용했는데, 나는 그냥 아이템 리스트 컴포넌트와 장바구니 창에서 같은 코드를 두 번 썼다... 수량을 추가할 때 주의해야할 점은, 값의 변경을 꼭 state 함수를 사용해서 해줘야 한다는 것이다.
따라서 나는 아래와 같은 방법을 사용해 장바구니 화면에 보여질 cartItems 상태의 현재 수량을 업데이트했다.
// 현재 클릭한 item 을 인자로 받아와서, cartItems 의 요소와 비교하여 같은 요소를 찾는다.
const targetItem = cartItems.find(cart => cart.itemId === itemId);
// 수량을 업데이트하기 위해 map 을 사용해, 특정 요소의 수량만 업데이트했다.
const newCartItems = cartItems.map(cart => (targetItem === cart ? {...targetItem, quantity} : cart));
setCartItems(newCartItems);
위 코드에서 나는 같은 요소인지 확인하기 위해 요소 전체를 비교해주었는데, 페어님께서는 id 값으로 비교를 하셨다. 다시 생각해보면 id 라는 값이 식별을 위한 유일한 값이기 때문에 전체를 비교하는 것 보다는 훨씬 더 효율적인 것 같다.
리뷰할만한 부분은 이정도? 컴포넌트의 구조와 상태 흐름 그리고 어떤 동작을 했을 때 어떻게 변경이 이루어지고, 그 함수들이 어떻게 연결되어 있는지만 파악하면 문제를 빨리 파악하고 해결할 수 있는 것 같았다. 일단 전체 코드 뼈대가 어느정도 구현이 된 상태에서 몇가지만 고치면 되는 것이었기 때문에 전체를 처음부터 설계해서 만드는 연습이 필요할 것 같다. 그리고 상태 흐름을 추적하는 것이 위 그림을 보면 알겠지만 drilling이 2단계 밖에 없었음에도 굉장히 지저분하고 머리아팠다.
✔️TodoList : styled-components 와 미디어쿼리
기존 css 를 styled-components 로 리팩토링 하고 있는데, 구조랑 css 가 크게 복잡하지 않아서 생각보다 시간이 많이 안걸렸다. 오늘 새롭게 알게된것은, + 선택자를 styled 엘리먼트 안에서 사용하면, 예를들어 &:focus + Label 이렇게 작성하면, 현재 엘리먼트가 focus 상태가 되었을 때 Label 에게 일어날 변화를 지정해줄 수 있다...! 기존에는 기본 스타일, focus 되었을 때 스타일, focus 되면 Label 에게 일어날 일을 다 따로 작성했어야 했는데 한 번에 쓸 수 있어서 좋았다.
const Input = styled.input`
width: 100%;
background-color: transparent;
border: none;
border-bottom: 0.1px solid var(--check-box);
transition: all 0.2s ease-in-out;
/* 생략... */
&:focus + Label {
top: -60px;
font-size: 0.9rem;
color: var(--font-color);
font-weight: 400;
}
`;
그리고 미디어 쿼리는 max-width 를 기준으로 나누어주었다. 기본적으로 css에서 작성하는 것과 크게 다르지 않았는데 역시 미디어쿼리가 적용될 styled 컴포넌트 안에서 작성해주면 된다. 지금 보니 미디어쿼리에 여러개의 포함된 요소가 영향을 받는다면 미디어쿼리 구문이 맨 마지막에 위치해야 변경이 되는군. 지금까지 완성된 부분은 아래와 같다.
진전이 빨리빨리 안되는 느낌인데, 주말에는 날 잡고 하루종일 이것만 붙잡고 해봐야겠다. 적용하고 싶은 것은 많은데... 일단 삭제 기능부터 만들어야겠다. 그리고 무턱대고 만들다보니 예쁘지 않은 간격도 자꾸 신경쓰이고 ㅋㅋ 다음에는 디자인 단계에서부터 더 꼼꼼하게 접근해야겠다...
✔️알고리즘
https://friedegg556.tistory.com/212
그저께쯤 데일리 코딩 문제로 나왔던 버블 정렬과 최적화를 다시 복습했다. 그리고 부분 집합 여부를 파악하는 알고리즘도 다시 복습했는데, 효율성은 잘 모르겠다만 배열을 새로 만들어서 푼 내 코드가 더 가독성이 좋지 않나 싶다. 내가 짜서 그런가...
🐈더 공부할 것
1. 리덕스, 상태관리 + useReducer 복습
2. TodoList : 삭제기능, inline edit 로 변경, gh-pages 배포
🐈오늘의 느낀 점
1. 오늘 확실히 깨달았는데, 저녁 먹고 난 이후 시간 관리가 진~짜 안된다. 이미 두 시간은 까먹고 들어가는 느낌인데 어떻게 해야 좋을지 모르겠다 ; ㅅ ; 밥을 먹기 전에는 배가 너무 고파서 힘이 없고, 밥을 먹으면 쉬고싶다.... 내일은 좀 더 잘 해봐야지...!
'TIL' 카테고리의 다른 글
[Day 52] 2022-0903 : Redux, git push --mirror, 완전탐색 알고리즘 (0) | 2022.09.03 |
---|---|
[Day 51] 2022-0901 : 리액트 상태관리, Redux (0) | 2022.09.01 |
[Day 49] 2022-0830 : React Custom Components - 자동완성 , 인라인 에디터 (0) | 2022.08.30 |
[Day 48] 2022-0829 : Custom Components, useEffect 복습, Git 협업 Flow (0) | 2022.08.29 |
[Day 46] 2022-0826 : CDD, CSS IN JS, SASS (0) | 2022.08.27 |