November 30, 2020
// 변경 전
// 원래 이런코드는 아니였는데, 좀 더 확연한 차이를 보기 위해 살짝 수정했다.
function calcDiscount(price, coupon){
let totalPrice = null;
if(coupon){
if(coupon.type === 'rate'){
totalPrice = price - ((coupon.discountRate/100)*price);
}else if(coupon.type === 'amount'){
totalPrice = price - coupon.discountAmount;
}
}else{
totalPrice = price;
}
return totalPrice;
}
// 변경 후
function calcDiscount(price, coupon){
if(!coupon) return price;
if(coupon.type === 'rate') return price - ((coupon.discountRate/100)*price);
if(coupon.type === 'amount') return price - coupon.discountAmount;
}
return
을 시켜서 조건문을 탈출하는것이 좋다고 한다.return
을 시키기 때문에, 조건문의 위치가 매우 중요!Redux
를 사용함에 있어, 나는 단순히 Flux
디자인패턴을 사용한다고 생각했다. 하지만 이번에 정말 나의 잘못된 생각이라는것을 느끼게되었다..JSX
는 사실상 거의 없는 수준이다.React Hook으로, UI와 관련되었을 경우 자신만의 상태값을 가지고 있을수 있다.
// 컨테이너 컴포넌트 HomeContainer.js
function HomeContainer(){
const {hotItems, cart} = SetHotItmes();
const dispatch = useDispatch();
const insertCart = useCallback((data) => {
dispatch(Actions.insertCart(data))
}, [dispatch])
const deleteCart = useCallback((id) => {
dispatch(Actions.deleteCart(id))
}, [dispatch])
return <Home
hotItems={hotItems}
cart={cart}
insertCart={insertCart}
deleteCart={deleteCart}
/>;
}
function SetHotItmes(){
const
{data : {productItems}, cart} = useSelector((state) => ({
data : state.data,
cart : state.cart
}), (left, right) => {
// App에서도 같은 부분이므로 하나로 합칠필요 있음.
const leftString = Object.entries(left.cart).toString();
const rightString = Object.entries(right.cart).toString();
if(leftString !== rightString) return false;
return true;
});
const hotItems = [...productItems].splice(0,3);
return {hotItems, cart};
}
// 홈은 app에게 상속받는 props값이 없기 때문에, 이후에는 app으로 인한 렌더링이 필요 없음
export default React.memo(HomeContainer, () => true);
// 프리젠테이셔널 컴포넌트 Home.js
function Home({hotItems, insertCart, deleteCart, cart}){
return(
<div className="home routeComp">
<div className="section">
<div className="sectionTitle">인기강의 TOP3</div>
<div className="hotItems sectionContent">
{
hotItems.map((item, index) => {
return(
<ProductsItem
data={item}
id={item.id}
key={item.id+index}
cart={cart}
insertCart={insertCart}
deleteCart={deleteCart}
/>
)
})
}
</div>
</div>
</div>
)
};
export default Home;
현재, React Hook이 개발되고 나서도 위처럼 나누는지 아니면, 하나의 파일안에서 커스텀 훅으로 분리하여 관리하는지는 잘 모르겠다..
중간에 컨테이너 컴포넌트를 하나 추가해야겠지..? 프리젠테이셔널 컴포넌트는 상태값에 조회를 할 수 없고, 그렇다고 하나하나 일일이 넘겨주는건.. Redux Hook을 사용하는 의미가 없으니깐..
비즈니스 로직을 구분하는것이 주된 목표이기 때문에, 프리젠테이셔널 컴포넌트에서 import하는것은 크게 상관없을 듯 하다.
여기서 인라인함수는,
.map
등으로 컴포넌트를 반복생성할 때, 동일한 함수가 지속적으로 생성되는것을 찝어주신것 같다.
사용할 때, 영향을 받는 값이 있다면, 두번째 인자인 배열에 해당 값을 넣어 변경시 새롭게 생성되도록 한다.
상위컴포넌트가 렌더링되었을 때, 관련이없는 하위컴포넌트도 렌더링이 된다. 첫번째 인자와 두번째 인자를 비교하여, 렌더링이 필요할 때만 false를 반환하도록 한다.