심진석

수정일

리액트에서 컴포넌트를 정의할 때 const를 사용할 필요는 없다

나는 몇년 전부터 리액트 컴포넌트를 function으로 바꾸었고, 최근에 한 주니어가 이를 사용하면 안된다면서 const를 사용해달라는 요청이 들어왔다.

그 분은 기술적인 지식이 전무한 개발자라 무시했지만, 이런 전통이 계속 이어져온다는게 조금 답답해서 글을 작성하게 되었다.

next.js, react 외에 글로벌 대기업은 전부 function를 사용하는데, 아직 한국에선 옛날 지식에 머물러있는 것 같다는 생각이 들었다.

왜 const인가?

ES6 이후로 var와 함께 거의 금기처럼 여겨지는 키워드가 있으니 그 것이 바로 function 이었다.

jQuery 기반의 복사/붙여넣기 개발이 대세였는데, 그러다보니 변수명이 겹치기 일상이었고, 어디서 문제가 발생했는데 디버깅하기 어려운 상황이 발생하게 되었다.

그리고 콜백함수와 객체지향의 시대였다보니 this를 잘 다루었어야했는데, 매일 헤깔리기도 했다. 또한 당시 리액트는 상태관리를 하려면 클래스 컴포넌트로 정의해야했다.

다만 완성되지 않은 class 문법은 사람들을 혼란스럽게 했고, this라는 키워드도 혼란이 있었기 때문에, this는 작동하지 못하게 Arrow Function이 스탠다드가 되었던 것이다.

위의 문제도 있었지만, 새로운 기능이라 힙하기도 했다. 그래서 나도 2~3년간 const와 arrow function을 사용했다.

물론 모두가 Arrow Function을 사용할 때 한 유명한 자바스크립트 개발자는 함수와 변수의 정의를 혼용하지 말라며 일관성 있게 함수는 function을 사용하는 방법을 권장하는 글도 있었다. 그런데 “모두가 const를 사용하는데 이게 무슨 말인가?” 하면서 그냥 넘겼던 기억이 있다.

지금은 function을 사용한다

지금은 function을 이용한다. 함수와 변수는 엄연히 다르다. 그러니까 함수는 function으로 정의하는게 일관성 있다고 생각했다.

webpack의 대중화 이후로 기능별로 파일을 잘 분할하면 이름이 겹칠 일이 없다. 무엇보다 리액트에선 this를 사용할 일이 거의 없다.

리액트를 사용하면 가장 많이 접할 react, nextjs의 공식문서 예제들은 전부 function을 이용하여 컴포넌트를 정의한다.

const를 옹호하는 사람들

함수 정의를 const로 하자는 사람들의 의견을 모아보았다.

규칙

function 키워드를 사용해서 불필요한 작업을 할 가능성을 열어두지 말고 순수함수인지 생성자 함수인지도 구분을 하자는 것이다. https://www.youtube.com/watch?v=LPEwb5plEoU

큰 회사에서는 다양한 사람이 있기 때문에 아마 서로 다른 다양한 문법을 사용하고 있기 때문에 그러한 걱정이 생긴 것 같다.

그런데… 이미 오래전부터 생성자 함수는 파스칼 케이스로, 일반 함수는 카멜 케이스로 이름 짓는다는 암묵적인 규칙이 뿌리내려 있기 때문에 이걸 헤깔려서 쓴다는건 조금 이해할 수 없다.

this의 경우 vue.js나 class를 사용하는 환경에서나 보이지 리액트에선 거의 쓰이지 않는다.

호이스팅이 걱정된다

jQuery 시절에는 호이스팅이 재앙 그 자체였다. 모든게 전역으로 선언이 되기에 함수 이름을 겹치지 않게 하기 위해 큰 노력이 필요했다.

그러나 webpack의 등장 이후엔 모듈 단위로 개발을 하다보니 이름이 겹치는 문제는 잘 생기지 않게 되었고 있다고해도 쉽게 찾아 해결할 수 있게 되었다.

호이스팅을 제대로 이해하지 못하는 일부 개발자들은 성능 문제가 있다는 주장도 있다. 하지만 const도 호이스팅이 된다는 점을 잊어선 안된다. 다만 TDZ라는 개념이 추가될 뿐이다.

 function foo() {
  // bar 변수는 밑에 있지만 사용할 수 있다.
  console.log(bar); // baz
}

const bar = 'baz';
foo(); 

실제로는 자바스크립트에 호이스팅이라는 작업은 존재하지 않는다. https://medium.com/nmc-techblog/what-is-hoisting-in-javascript-bf73980d9dac 단지 쉽게 설명하기 위해 만들어진 추상적인 단어이다.

성능 문제가 있다?

const 문법이 나온지 얼마 안됐을 때는 const가 var나 let에 비해 확실히 느려서 사용을 고려해봐야한다는 포스팅도 나올 정도였다.

그래도 사용했다. babel을 거치면 var로 변환되었기 때문에 리액트 개발자에겐 중요하진 않았다.

찾아보니 V8 엔진 개발자의 답변도 있었다.

스택오버플로우 답변 링크

차이가 없다고 한다..

Arrow Function 표현식은 바인딩이나 프로토타입도 없으므로 성능에서 분명 우세할 수 있다라는 말은 그럴싸한데, 실제로 무작위 순서로 1억번을 실행하는 테스트를 여러번 해봤지만, 결과가 매번 다르게 나오고, 차이가 있어도 1ms이다.

취향차이

결론은 취향차이라고 말하고 싶다.