-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] [6팀 소수지] [Chapter 2-2] 디자인 패턴과 함수형 프로그래밍 #2
base: main
Are you sure you want to change the base?
Conversation
… - 쿠폰 적용하기 계산 함수 분리
// 장바구니 내 모든 상품 총액 계산 함수 | ||
export const calculateCartTotal = (cart: CartItem[], selectedCoupon: Coupon | null) => { | ||
const { totalBeforeDiscount, totalAfterDiscount: initialTotalAfterDiscount } = | ||
calculateTotalDiscount(cart); | ||
|
||
const { totalAfterDiscount, totalDiscount } = applyCouponDiscount( | ||
initialTotalAfterDiscount, | ||
totalBeforeDiscount, | ||
selectedCoupon | ||
); | ||
|
||
return { | ||
totalBeforeDiscount, | ||
totalAfterDiscount, | ||
totalDiscount: Math.round(totalDiscount), | ||
}; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
함수형으로 깔끔하게 작성이 되었네요 👍
totalAfterDiscount을 initialTotalAfterDiscount으로 별칭을 만들어 준건 어떠이유에서 인지 알 수 있을까요?!
applyCouponDiscount에서 return하는 값이 totalAfterDiscount라서 그런거라면
calculateTotalDiscount를 호출하면서 가져온 리턴 값을 구조분해 하지않고 변수를 그대로 applyCouponDiscount으로 전달하면 해소가 되지 않을까?
생각이 들었습니다 !
calculateTotalDiscount에서 리턴하는 totalBeforeDiscount,totalAfterDiscount 두개의 값 모두 결국 applyCouponDiscount에 전달되기도 하니까요 !
수지님 생각은 어떠신지 궁금합니다 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이번 한 주도 고생하셨습니다!
act(() => { | ||
result.current.addToCart(testProduct); | ||
}); | ||
|
||
act(() => { | ||
result.current.updateQuantity(testProduct.id, 2); | ||
}); | ||
|
||
act(() => { | ||
result.current.applyCoupon(testCoupon); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저랑 창엽님도 localStorage 훅을 적용하고 나서 테스트를 통과 못하길래 저렇게 나눠주었습니다..!
setState()
의 비동기와 관련되어있는 것 같은데 정확한 원인은 모르겠습니다..ㅎㅎ README에도 의문점으로 남겨주셨더라구요..!
의문점은 해결 되셨을까요? 궁금합니다ㅎㅎ
export const useLocalStorage = <T>(key: string, initialValue: T): Storage<T> => { | ||
const [storedItem, setStoredItem] = useState<T>(() => { | ||
try { | ||
const product = window.localStorage.getItem(key); | ||
return product ? JSON.parse(product) : initialValue; | ||
} catch (error) { | ||
console.log(error); | ||
return initialValue; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
에러처리도 하셨네요..! 꼼꼼하신 것 같습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍👍👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SSR 환경에 대한 고려도 하신 것 같습니다! 멋져요! 💯 👍 🥇
const key = 'testKey'; | ||
const initialValue = { name: 'Test', quantity: 1 }; | ||
|
||
beforeEach(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
localStorage 훅을 테스트하기 위해서 이렇게 할수도 있군요 배워갑니다~
|
||
const setCartItem = (product: T | ((prev: T) => T)) => { | ||
try { | ||
const itemToStore = product instanceof Function ? product(storedItem) : product; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typeof product === 'function'
이런 식으로 비교하는 코드를 많이 본 것 같은데, 이 방식은 처음 봐요! 혹시 어떤 이유에서 이렇게 사용하셨는지 알 수 있을까요~? 🤓
export const useLocalStorage = <T>(key: string, initialValue: T): Storage<T> => { | ||
const [storedItem, setStoredItem] = useState<T>(() => { | ||
try { | ||
const product = window.localStorage.getItem(key); | ||
return product ? JSON.parse(product) : initialValue; | ||
} catch (error) { | ||
console.log(error); | ||
return initialValue; | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SSR 환경에 대한 고려도 하신 것 같습니다! 멋져요! 💯 👍 🥇
if (exisitingItem) { | ||
return cart.map((item) => | ||
item.product.id === product.id | ||
? { ...item, quantity: Math.min(item.quantity + 1, product.stock) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
product.stock
들은 getRemainingStock
함수로 계산해 사용할 수 있을 것 같아요! 🤓
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
전 테스트 코드를 작성하지 못했는데 수지님꺼 보면서 많이 배우고 갑니다 ~!
let totalBeforeDiscount = cart.reduce((sum, item) => sum + item.product.price * item.quantity, 0); | ||
|
||
let totalAfterDiscount = cart.reduce((sum, item) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
두 변수 다 const로 수정할 수 있을 것 같습니다~!
과제 체크포인트
기본과제
React의 hook 이해하기
함수형 프로그래밍에 대한 이해
Component에서 비즈니스 로직을 분리하기
비즈니스 로직에서 특정 엔티티만 다루는 계산을 분리하기
Component에서 사용되는 Data가 아닌 로직들은 hook으로 옮겨졌나요?
주어진 hook의 책임에 맞도록 코드가 분리가 되었나요?
계산함수는 순수함수로 작성이 되었나요?
심화과제
뷰데이터와 엔티티데이터의 분리에 대한 이해
엔티티 -> 리파지토리 -> 유즈케이스 -> UI 계층에 대한 이해
Component에서 사용되는 Data가 아닌 로직들은 hook으로 옮겨졌나요?
주어진 hook의 책임에 맞도록 코드가 분리가 되었나요?
계산함수는 순수함수로 작성이 되었나요?
특정 Entitiy만 다루는 함수는 분리되어 있나요?
특정 Entitiy만 다루는 Component와 UI를 다루는 Component는 분리되어 있나요?
데이터 흐름에 맞는 계층구조를 이루고 의존성이 맞게 작성이 되었나요?
과제 셀프회고
과제에서 좋았던 부분
1. 순수함수
2. 불변성
pass by reference
pass by value
3. 선언적 패턴
과제를 하면서 새롭게 알게된 점
1.
beforeEach
와afterEach
vi.fn()
을 통해getItem
과setItem
메서드를 모킹합니다.2.
renderHook
을 통해 훅 테스트3.
act
를 통해 상태 업데이트 테스트과제를 진행하면서 아직 애매하게 잘 모르겠다 하는 점, 혹은 뭔가 잘 안되서 아쉬운 것들
act
과정에서 여러 상태 업데이트를 한번에 처리하여 업데이트 된 상태가 즉시 반영되지 않음act
를 각 상태 업데이트로 분리하여 상태 변경을 순차적으로 이룰 수 있도록 테스트 코드 변경useLocalStorage
에setItem
에서 로컬 스토리지를 초기화 처리를 했는데 왜 오류가 발생할까?리뷰 받고 싶은 내용이나 궁금한 것에 대한 질문
폴더구조 관련