본문 바로가기
Modern React Deep Dive/01장 리액트 개발을 위해 꼭 알아야 할 자바스크립트

1.2.4 함수를 만들 때 주의해야 할 사항

by Whiimsy 2024. 4. 2.

1.2.4 함수를 만들 때 주의해야 할 사항

함수의 부수 효과를 최대한 억제하라

  • 함수의 부수 효과(side-effect)란 함수 내의 작동으로 인해 함수가 아닌 함수 외부에 영향을 끼치는 것을 의미
  • 이러한 부수 효과가 없는 함수를 순수 함수라 하고, 부수 효과가 존재하는 함수를 비순수 함수라고 함
  • 즉, 순수 함수는 부수 효과가 없고, 언제 어디서나 어떠한 상황에서든 동일한 인수를 받으면 동일한 결과를 반환해야 함. 그리고 이러한 작동 와중에 외부에 어떠한 영향도 미쳐서는 안됨
  • function PureComponent(props) {
      const { a, b } = props
      return <div>{a + b}</div>
    }
    위 컴포넌트는 앞선 기준에 따라 순수한 함수형 컴포넌트로 분류할 수 있음. props의 값을 기준으로 a, b를 더하고, 그 결과를 HTMLDivElement로 렌더링함. 외부에 어떤 영향을 미치지도 않았고, 언제 어디서든 동일한 인수를 받아 동일한 결과를 반환하기 때문에 순수한 함수형 컴포넌트라 볼 수 있음
  • 장점) 순수 함수는 언제 실행되든 항상 결과가 동일하기 때문에 예측 가능하며 안정적임
  • 그렇다면 어떻게서든 항상 순수함수로만 작성해야 할까?
    • 그렇지 않다. 웹 애플리케이션을 만드는 과정에서 부수 효과는 어떻게 보면 피할 수 없는 요소임. 컴포넌트 내부에서 API를 호출하는 것도 외부에 어떠한 영향(HTTP request)을 끼쳤으므로 부수 효과임. console.log도 브라우저의 콘솔 창이라는 외부에 영향을 미쳤으므로 부수 효과임. HTML 문서의 title을 바꿨다면 이 또한 외부에 영향을 미쳤으므로 부수 효과임. 이러한 부수 효과는 웹 애플리케이션 개발에 있어 피할 수 없는 요소 중 하나임. 다만, 이러한 부수 효과를 최대한 억제할 수 있는 방향으로 함수를 설계해야한다는 것. 리액트의 관점에서 본다면 부수 효과를 처리하는 훅인 useEffect의 작동을 최소화하는 것이 그 일환이라 할 수 있음. useEffect의 사용은 피할 수 없지만 최소한으로 줄임으로써 함수의 역할을 좁히고, 버그를 줄이며, 컴포넌트의 안정성을 높일 수 있음
  • 따라서) 자바스크립트 함수에서는 가능한 한 부수 효과를 최소화하고, 함수의 실행과 결과를 최대한 예측 가능하도록 설계해야 함. 예측 가능한 단위의 부수 효과가 작은 함수를 설계하면 개발자에게 많은 도움을 줌

가능한 한 함수를 작게 만들어라

  • 자바스크립트 개발자들이 프로젝트 만들 때 사용하는 ESLint에는 max-lines-per-function이라는 규칙이 있음. 함수당 코드의 길이가 길어질수록 코드 냄새(문제를 일으킬 여지가 있는 코드)가 날 확률이 커지고, 내부에서 무슨 일이 일어나는지 추적하기 어려워짐. 이 규칙에서는 기본값으로 50줄 이상이 넘어가면 과도하게 커진 함수로 분류하고 경고 메세지를 출력함. 그 외에도 중첩이 얼마나 많이 있고 콜백은 얼마나 많은지도 이 규칙에서 확인 가능. 이 규칙의 요점은 하나의 함수에서 너무나 많은 일을 하지 않게 하는 것.
  • 함수는 하나의 일을, 그 하나만 잘하면 된다(Do One Thing and Do It Well). 그것이 함수의 원래 목적인 재사용성을 높일 수 있는 방법임
  • 그렇다면 함수의 가독성을 높일 수 있는 최적의 함수 길이는 얼마일까? 이는 상황에 따라 다를 것.. 다만, 가능한 한 함수의 크기를 작게 하는 것이 좋음

누구나 이해할 수 있는 이름을 붙여라

  • 클린 코드나 리팩터링 등에서도 많이 언급되는 문제지만, 가능한 한 함수 이름은 간결하고 이해하기 쉽게 붙이는 것이 좋음
  • 본인이 사용하는 프로젝트의 프레임워크에 Terser*가 설치돼 있다면 한글로 네이밍하는 것도 좋은 방법이 될 수 있음
    • Terser: 자바스크립트 코드를 맹글링(mangling, 코드를 컴파일러가 이해할 수 있는 수준에서 단순화) 및 압축하는 도구
    • 실제 개발 단의 코드 크기나 번들링 속도에 있어서는 약간의 부담이 될 수 있지만, 실제 서비스되는 코드에는 영향을 미치지 않고, 또 무엇보다 한글이 편한 한국 개발자들에게 함수나 변수 네이밍에 있어 자유를 준다는 점에서 고려해 볼 만함
    • 물론 Terser가 작동하지 않는 경우도 있으므로 실제 번들링된 결과를 주의 깊게 살펴봐야 함
  • 리액트에서 사용하는 useEffect나 useCallback 등의 훅에 넘겨주는 콜백 함수에 네이밍을 붙여준다면 가독성에 도움이 됨
    useEffect(function apiRequest() {
      // ... do something
    }, [])
    물론 위와 같이 useEffect의 콜백 함수에 이름을 붙여준다고 한들 apiRequest()와 같은 형태로 호출하거나 접근할 수 있는 것은 아님. 그러나 useEffect 같은 부수 효과를 일으키는 함수가 많아질수록 굳이 useEffect 코드를 유심히 살펴보지 않더라도 어떤 일을 하는지, 또 어떻게 작동하는지를 단번에 알아채는 데 도움이 될 것임. 또한 이후에 살펴볼 크롬 디버깅에서도 네이밍이 돼 있는 편이 추후에 디버깅하는 데 많은 도움이 됨