티스토리 뷰

reduce()

  • map() 대신 사용
  • array의 모든 요소를 체크하고 누적된 값을 리턴하기 좋은듯
  • 반복문이나 값을 계산하기 위한 변수를 따로 선언하지 않아도 결과 값을 출력할 수 있어서 코드가 깔끔해보인다.

 

array.reduce(callback, 초기값);
  • array: 콜백함수를 돌리는데 사용할 인수를 가진 배열
  • callback: 배열의 각 요소에 대해 실행될 함수
    • 사용가능 한 인수들
    • accumulator: 누적된 값
    • currentValue: 현재 처리 중인 요소
    • currentIndex: (선택사항) 현재 처리 중인 인덱스
    • array: (선택사항) reduce()가 호출된 원본 배열
  • 초기값: 생략시 array의 첫 번째 요소가 초기 누적값이 됨

 

예시

const array = [1, 2, 3, 4, 5];

// reduce를 사용하여 array의 모든 요소의 합을 계산

const sum = array.reduce((accumulator, currentValue) => {
  return accumulator + currentValue);
}, 0); // 초기값 : 0

console.log(sum) // 15

const sum = array.reduce((accumulator, currentValue) => {
  return accumulator + currentValue);
}, 100); // 초기값 : 100

console.log(sum) // 115

 

1. 이제 reduce()를 사용해서 map()을 걷어내보자.

// 리팩토링 전
function Payment() {
    const state = useSelector((state) => state.cartItem);
    let [sumPrice, setSumPrice] = useState(0);
    let priceArr = [];

    if (state.length > 0) {
        state &&
            state.map((a, i) => {
                let amountPrice;
                if (state[i].checked) {
                    amountPrice = state[i].price * state[i].count;
                } else {
                    amountPrice = 0;
                }
                return priceArr.push(amountPrice);
            });
    } else {
        sumPrice = 0;
    }
}
// 리팩토링 후
function Payment({ cartItem }) {
    const [sumPrice, setSumPrice] = useState(0);

    const calculateSumPrice = () => {
        if (!cartItem) return;

        const totalAmount = cartItem.reduce((sum, item) => {
            if (item.checked) {
                return sum + item.price * item.count;
            }
            return sum;
        }, 0);
        setSumPrice(totalAmount);
    };

 

2. 불필요하게 두번 계산하던 것도 calculateSumPrice란 변수에 담아서 재사용하기 + setTimeout 제거

// 리팩토링 전
useEffect(() => {
    setTimeout(() => {
        if (priceArr.length > 0) {
            let a = priceArr.reduce((sum, itemPrice) => sum + itemPrice);
            setSumPrice(a);
        }
    }, 100);
});
// 리팩토링 후
useEffect(() => {
    calculateSumPrice();
});

 

3. return()에서 직접 연산하던 부분도 추상화하기

// 리팩토링 전
return (
    ...
    <dl className="amount">
        <dt className="amount-item">총 상품금액</dt>
        <dd className="amount-price">{sumPrice.toLocaleString()}원</dd>
        <dt>배송비</dt>
        <dd>+{sumPrice === 0 ? 0 : sumPrice >= 30000 ? 0 : SHIPPING}원</dd>
    </dl>
    <dl className="total">
        <dt>결제예상금액</dt>
        <dd>
            {sumPrice === 0
                ? 0
                : sumPrice >= 30000
                ? sumPrice.toLocaleString()
                : (sumPrice + shipping).toLocaleString()}
            원
        </dd>
    </dl>
    ...
)
// 리팩토링 후
const calculateSumPrice = () => {
    ...
    const renderShippingCost = () => {
        if (sumPrice >= 30000) {
            return 0;
        }
        return SHIPPING_COST;
    };

    const estimatedPayment = () => {
        if (sumPrice === 0) {
            return 0;
        }
        const totalPrice = sumPrice + (sumPrice >= 30000 ? 0 : SHIPPING_COST);
        return totalPrice.toLocaleString();
    };
    ...
    return (
        ...
        <dl className="amount">
            <dt className="amount-item">총 상품금액</dt>
            <dd className="amount-price">{sumPrice.toLocaleString()}원</dd>
            <dt>배송비</dt>
            <dd>+{renderShippingCost()}원</dd>
        </dl>
        <dl className="total">
            <dt>결제예상금액</dt>
            <dd>{estimatedPayment()}원</dd>
        </dl>
        ...
    );
}

'Library | Framework > React JS' 카테고리의 다른 글

리팩토링  (0) 2023.08.23
[React] async  (0) 2022.11.12
[React] PWA  (0) 2022.11.12
[성능개선] batch, useTransition, useDeferredValue  (0) 2022.11.10
[성능개선] 재렌더링 금지, memo, useMemo  (0) 2022.11.10
댓글