최근 회사에 새로 들어오신 분이 Next 를 한 번도 해보지 않은 분이셨는데,
함께 작업하게 되면서 Next 혹은 JS 초보분들이 보실 수 있는 코드 작성 팁을 굵 직하게 많이 사용하실 것 같은 내용만
몇 가지 적어보려고 한다. (생각나거나 또 생긴다면 정리할 예정)
Next 개발 2년차가 되어서도 늘 느끼지만 내 코드가 모두 정답은 아닐 수 있고,
지금 적은 내용들도 나중에 가면 바뀔 수도 있으니 가볍게 읽어보셨으면 한다.
(코드 작성이 옳다, 그르다 보다는 지금 현 상황에서 Next 를 이용할 때 이런 것은 주의하는게 좋다~ 가 이 글의 요지란 이야기.)
useEffect 의 사용은 최대한 적게
useEffect 는 최초 한 번 혹은 의존성 리스트 안의 요소가 호출되었을 때 실행되는 성질이 있어,
"초보분들이 변수 값이 바뀌었을 때" 에 초점을 두고 4, 5개씩 사용하는 경우가 있는다.
하지만 우리가 초점을 두어야하는 내용은 "의존성에 포함된 변수" 이다.
의존성에 2개가 있다면 2개가, 10개가 있다면 10개 모두 한 번 호출될 때 재랜더된다는 것이다.
const [text, setText] = useState("");
const [saving, setSaving] = useState(false);
useEffect(() => {
if (!!text && saving) {
console.log("저장할게!")
}
}, [text, saving]);
예를 들어
1. input 에 있는 값을
2. onChange 로 바꿔서 state 에 저장하고
3. 저장 버튼을 누르면 saving 이 true 로 변한다
위 과정을 거친다면 사용자가 input 에 값을 입력할 때마다 "저장할게!" 가 뜨게 된다.
이렇게 useEffect 를 사용할 일이 생긴다면 최대한 이벤트 호출을 통해서 값이 변경되는 방향으로 고민해보자.
하나의 useEffect 안에 관련없는 여러 개의 작업을 진행하지 않도록 하자.
const [text, setText] = useState("");
const [checked, setChecked] = useState(false);
const [saving, setSaving] = useState(false);
useEffect(() => {
// 체크박스 핸들링 시 콘솔
if (checked) {
console.log("체크박스 on")
}
// 인풋 작성 후 저장했을 시 콘솔
if (!!text && saving) {
console.log("저장할게!")
}
}, [checked, text, saving]);
위 코드처럼 두 가지 다른 동작을 하는 코드를 하나의 useEffect 로 묶어 작업하는 실수를 더러 한다.
1번에서 말했듯이 의존성 리스트에 들어간 요소들이 늘어날수록 무한루프의 위험성이 커진다.
하나의 useEffect 에서는 관련이 있는 작업이 아니면 분리해주도록 하자.
조건문이 짧을 때는 삼항연산자를 사용하자.
조건이 길 때는 if 문이나 case 를 이용하는 것이 가독성 면에서 더 좋을 수 있지만,
조건이 짧을 때는 코드라인 수를 줄일 수 있도록 삼항 연산자를 이용하는 것이 좋다.
덧붙여 if 문은 개인적으로 3번 이상 사용하는 것은 좋은 코드라고 생각하지 않기 때문에(가독성이 좋지 않음),
부득이하게 3번 이상 써야한다면 case 와 if 를 섞어서 사용하도록 하자.
forEach 사용을 조심하자.
forEach 는 break 가 존재하지 않기 때문에 주의가 필요하다.
필자가 초보일 시절에는 forEach 가 짧은 코드라인으로 for 과 같은 기능을 할 수 있어서 많이 썼지만,
현재는 퍼포먼스를 위해 주의보단 지양하는 것이 더 낫지 않을까 생각이 들어 쓰지 않는다.
return 할 컴포넌트 내에서의 연산자 사용
// 사과가 없으면 바나나를 변수에 담음
const basket = useMemo(() => apple ? apple : banana, [])
// !empty 가 true 일 때 사과 컴포넌트 대신 바나나 컴포넌트를 리턴
<div>
{ !empty ? <Apple /> : <Banana /> }
</div>
-------------------------------------------------------------------
// empty 가 true 일 때 바나나 컴포넌트를 리턴
<div>
{ empty && <Banana /> }
</div>
// 사과가 없으면 바나나 리턴
<div>
{ apple ?? banana }
</div>
첫 번째 예시처럼 삼항연산자는 동일하게 컴포넌트 return 내부에서 사용할 수 있다.
(html 태그 내 {} 에서는 if 문을 사용할 수 없으니 삼항연산자를 이용하면 동일하게 기능할 수 있다.)
두 번째 예시 같은 상황은 삼항연산자를 사용하지 않아도 되니 참고하자!
변할 수 있는 값을 변수에 담고 싶다면 uesMemo 를 사용하자.
const [example, setExample] = ['abcd', 'a', 'abcde'];
// 올바르지 않은 사용법
const filterExample = example.filter((item) => item.length > 4);
// 올바른 사용법
const filterExample = useMemo(() => example.filter((item) => item.length > 4), [example])
위 경우처럼 값이 변할 수 있는 변수를 또 다른 변수에 넣고 싶을 때는 useMemo 를 사용해야한다.
callback 에 참고할 변수를 담아두면, useMemo 에서 값이 바뀌었을 때를 감지하여 변수값을 자동으로 갱신한다.
다만, useMemo 을 단순 계산을 위해 사용하는 것은 지양한다.
useMemo 도 state 처럼 캐싱이 되므로 일정 메모리를 차지하며 동작하기 때문이다.
꼭 복잡한 계산이거나, 정말 자주 사용되는 단순 계산일 경우에만 useMemo 를 사용하도록 하자.
(개인적 견해) null 보다는 undefined 를 사용하자
이건 팀마다 성향이 다를 수 있지만 개인적으로는 undefined 사용을 지향하는 편이다.
undefined 사용하지마라, null 의 고질적인 문제 때문에 undefined 가 나온거다 등등.. 의견이 분분하지만 undefined 에 한표
undefined 는 아예 아~무것도 값을 담을 공간도 없는 상태이고,
null 은 값을 담은 공간은 있지만 값은 비어있는 상태를 이야기한다.
(하지만 undefined 에 아주 적은 메모리를 차지하는 더미 데이터가 들어가있다는 이야기가 있음...)
약간이지만 메모리적인 이점도 있고, 개인적으로 null 보다는 undefined 가 편해서 대부분의 코드에 사용한다.
물론 명확하게 값이 있어야하고 없어야함이 드러나야 디버깅이 편하다 등등.. 의 이유로 null 을 쓸 때 잘 생각해보고 쓰자.
https://www.reddit.com/r/typescript/comments/11dpu05/undefined_vs_null/?rdt=52567
(레딧 null vs undefined 에 대한 유저들의 반응. 사람마다 다른데 프로젝트 특성에 따라 쓰는게 최고다.)
개인적으로 우리 팀 후임들에게 부탁하고 싶은점..
개인적으로 코드리뷰를 할 때 초보분들도 의견 공유를 해주시고,
모르시는게 있을 땐 혼자 끙끙 앓는 게 아니라 그때그때 질문을 팍팍 해주셨으면 좋겠습니다. 바쁘지 않다면 성심성의껏 도와드릴게요.
가끔 초보분들의 툭 던지는 질문도 저희 주니어들에게 뼈와 살이 될 수 있다고 생각해서 (가끔 허를 찌르시니...),
좋은 정보는 공유해주시고 충분히 고민해봤지만 모르겠는 내용은 무서워 하시지 않으셨으면 좋겠어요.
모르는 건 찾아보고 함께 실력을 쌓아가는 동료로 일하고 싶어요 :)
'🔥 Javascript > 🖤 Next' 카테고리의 다른 글
Next.js 공식 홈페이지에서 추천하는 빌드 속도 올리기(+SWC, 터보팩) (0) | 2023.01.11 |
---|