[React] 코드 리팩토링으로 비슷한 기능을 하는 함수 합치기

eunjin·2020년 12월 27일
1

React Study

목록 보기
1/6

리액트로 장바구니 페이지의 기능을 짜다가, 장바구니 수량을 수정하는 기능을 추가하게 되었다. 처음에는 addItem()과 subtractItem() 메서드 두 개를 썼다가, 하나로 합칠 수 있다는 멘토님의 리뷰에 어떻게 합칠지 고민하기 시작했다.

이전에 비효율적으로 짠 함수는 다음과 같다.

addItem = (id) => {
    const { cartItems } = this.state
    const changedStatus = cartItems.map(item => {
      if (item.productId === id) {
        item.amount++
      }
      return item
    })
    this.setState({
      cartItems: changedStatus
    })
  }

  subtractItem = (id) => {
    const { cartItems } = this.state
    const changedStatus = cartItems.map(item => {
      if (item.productId === id) {
        item.amount--
      }
      return item
    })
    this.setState({
      cartItems: changedStatus
    })
  }

item의 수량을 한 개씩 추가하고 빼는 연산만 제외하고는 완전히 똑같은 코드로 이루어져 있다. 여기에서 나는 고민을 하기 시작했다. onClick 메서드를 주는 버튼에 target 값을 각각 'add', 'subtract' 로 지정하고, 그 다음에 함수에서 e.target.value로 접근해서 내가 클릭하는 버튼의 value에 따라서 연산을 할 수 있지 않을까?

<div className="modify">
    <span 
	id={id}
	type={'plus'}
	className={`plus ${ifSoldOutAddThisClass}`} 
	onClick={() => isInStock ? modifyItemAmount(id) : undefined}></span>
    <span className={`amount ${!isInStock && 'soldOut'}`}>{amount}</span> 
    <span 
	id={id}
	type={'minus'}
	className={`subtract ${ifSoldOutAddThisClass}`}
	onClick={() => isInStock ? modifyItemAmount(id) : undefined}></span>
</div>

그런데 e.target.value로 접근하는 게 불가능한 거였다. e.target.className은 접근이 되는데 왜 value는 접근이 안되는 건지 이해할 수가 없었지만, 빠르게 납득을 하고 팀원에게 도움을 요청했다. 팀원의 조언은 modifyItemAmount() 함수에 id와 더불어 'add', 'subtract'라는 인자를 각각 넣어주면 된다고 했다. 그래서 다시 함수를 만들어보았다.

일단 jsx에서는 함수의 인자로 'plus'와 'minus'를 각각 넣어주었다.

  //jsx
    <div className="modify">
      <span 
	id={id}
	className={`plus ${ifSoldOutAddThisClass}`} 
	onClick={() => isInStock ? modifyItemAmount(id, 'plus') : undefined}></span>
      <span className={`amount ${!isInStock && 'soldOut'}`}>{amount}</span> 
      <span 
	id={id}
	className={`subtract ${ifSoldOutAddThisClass}`}
	onClick={() => isInStock ? modifyItemAmount(id, 'minus') : undefined}></span>
    </div>

그리고 함수에서는 id, modify라고 변수 이름을 지정해 주고, modify가 'add'라는 값을 가진다면 장바구니 수량을 더해 주고, 그렇지 않으면 빼 주는 연산을 수행하도록 하였다.

  modifyItemAmount = (id, modify) => {
    const { cartItems } = this.state
    const changedStatus = cartItems.map(item => {
      if (item.productId === id) {
        modify === 'plus' ? item.amount++ : item.amount--
      }
      return item
    })
    this.setState({cartItems: changedStatus})
  }

25줄짜리 코드를 절반 이하로 줄였다. 더 줄여볼 수 있겠지만, 오늘은 이렇게 두 번째 인자를 부여하는 방법을 새로 알았다는 것만으로도 엄청난 수확인 것 같다. 어디에나 쓸 수 있을 것 같다.

profile
빵굽는 프론트엔드 개발자

0개의 댓글