Showing Posts From
성장
- 26 Dec, 2025
코드리뷰 후 '감사합니다' 클릭하는 순간의 마음
코드리뷰 후 '감사합니다' 클릭하는 순간의 마음 빨간 알림이 뜬다 슬랙 알림이 떴다. 심장이 쿵 내려앉는다. "@이신입 코드리뷰 남겼어요 👍" 이모지가 웃고 있지만 나는 못 웃는다. 일단 깃허브를 켠다. PR 탭을 누른다. 손가락이 미세하게 떨린다. 댓글이 7개다. 7개. 첫 번째 댓글을 연다. "여기 useCallback으로 감싸는 게 좋을 것 같아요. 지금은 매 렌더링마다 함수가 재생성되고 있어서요." useCallback. 들어봤다. 강의에서 봤다. 근데 왜 쓰는 거더라. 일단 고개를 끄덕인다. 아무도 안 보는데 끄덕인다.구글링을 시작한다 새 탭을 연다. "useCallback 언제 쓰나요" 검색한다. 벨로그 글이 나온다. 읽는다. 아 뭔가 알 것 같다. 스크롤을 내린다. 모르겠다. 두 번째 글을 연다. "useCallback vs useMemo 차이점" 제목이다. 차이점이 아니라 useCallback만 알고 싶은데. 세 번째 글은 영어다. 스택오버플로우다. 패스한다. 다시 첫 번째 글로 돌아간다. 코드 예시를 본다. 복사한다. 메모장에 붙여넣는다. 시계를 본다. 벌써 20분이 지났다. 아직 첫 번째 댓글이다. "빨리 수정해야 하는데..." 입에서 나온다. 혼잣말이다.두 번째 댓글을 연다 "dependency array에 count를 넣어주세요. 지금은 stale closure 문제가 있을 수 있어요." stale closure. 처음 보는 단어다. 아니다. 본 것 같기도 하다. 기억이 안 난다. 또 구글링한다. "stale closure 뜻" 검색한다. 영어 글만 나온다. 한국어로 바꾼다. "오래된 클로저 문제" 이렇게 나온다. 오래된 클로저. 클로저도 잘 모르는데. useEffect 강의를 다시 찾는다. 인프런에 저장해둔 거다. 49분짜리 영상이다. "일단 나중에 보자." 북마크에 넣는다. 이미 북마크는 87개다. 세 번째 댓글을 연다. "early return 패턴 사용하면 가독성이 더 좋을 것 같습니다." 이건 뭔지 안다. if 문을 먼저 쓰는 거다. 이건 할 수 있다. 처음으로 뭔가 이해했다. 기분이 좋다. 3초 정도. 네 번째부터는 포기한다 "불필요한 props drilling이 있네요. Context API 고려해보시겠어요?" Context API. 들어봤다. 쓴 적은 없다. "여기 memo 처리하면 리렌더링 줄일 수 있을 거예요." memo. React.memo. 이것도 들어봤다. 언제 쓰는지는 모른다. "이 부분 custom hook으로 분리하면 어떨까요?" custom hook. 만들어본 적 없다. 선배들 코드에서만 봤다. 마지막 댓글을 연다. "전반적으로 잘 작성하셨어요! 몇 가지만 수정하면 될 것 같습니다 👍" 이 한 줄이 제일 중요하다. "잘 작성하셨어요" 이 부분. 적어도 완전히 망친 건 아니구나. 조금 안심한다.'감사합니다' 버튼을 누른다 이제 답을 달아야 한다. 첫 번째 댓글에 답한다. "아 감사합니다! 수정하겠습니다 👍" 두 번째도 똑같이 쓴다. "감사합니다! 반영하겠습니다 👍" 세 번째는 조금 바꾼다. "오 좋은 의견 감사합니다! 수정할게요 👍" 네 번째부터는 복사 붙여넣기다. 이모지만 바꾼다. 👍에서 🙏로. 마지막 댓글엔 "피드백 감사합니다! 많이 배웠습니다 🙏" 이렇게 쓴다. 많이 배웠습니다. 사실 반만 이해했다. 아니다. 30%도 이해 못 했다. 근데 뭐라고 써야 하나. "죄송한데 이해 못 했어요" 이렇게 쓸 수는 없다. 물어보면 된다고 하는데 7개를 다 물어볼 수는 없다. "바쁘신데 죄송합니다" 이것도 이상하다. 그냥 "감사합니다"가 제일 무난하다. 언제나 그렇다. 실제로 수정을 시작한다 early return부터 한다. 이건 할 수 있다. if 문을 위로 올린다. 커밋한다. "refactor: apply early return pattern" useCallback을 추가한다. 아까 복사한 코드를 참고한다. 함수를 감싼다. 의존성 배열에 뭘 넣어야 하는지 모르겠다. 일단 빈 배열 넣는다. 에러가 난다. ESLint가 뭐라고 한다. "React Hook useCallback has a missing dependency" 의존성 배열에 count를 넣는다. 에러가 사라진다. 된 거 같다. 근데 왜 이렇게 해야 하는지는 모르겠다. 일단 넘어간다. Context API는 패스한다. 시간이 너무 오래 걸릴 것 같다. "다음 PR에 반영하겠습니다" 댓글을 단다. custom hook도 패스한다. 같은 답변을 단다. memo는... 일단 구글링부터 한다. 30분 후에 포기한다. 이것도 "다음에 반영하겠습니다" 댓글을 단다. 다시 리뷰를 요청한다 수정한 코드를 푸시한다. 슬랙에 멘션한다. "@김선배님 수정 완료했습니다! 확인 부탁드립니다 🙏" 10분 후 답장이 온다. "확인했어요 👍 Approve 했습니다~" Approve. 승인이다. 됐다는 거다. 가슴이 뛴다. 진짜로 뛴다. "감사합니다!!" 답장한다. 이번엔 느낌표 2개다. 머지 버튼을 누른다. "Merge pull request" 초록색 버튼이다. 클릭한다. 화면이 보라색으로 바뀐다. "Pull request successfully merged and closed" 성공이다. 첫 PR이 머지됐다. 기분이 좋다. 근데 동시에 불안하다. "저 코드가 진짜 괜찮은 걸까. 내가 제대로 이해한 걸까." 모르겠다. 일단 됐으니까 된 거다. 그렇게 생각하기로 한다. 저녁을 먹는다 편의점에 간다. 김치볶음밥 도시락을 산다. 3900원이다. 사무실로 돌아온다. 전자레인지에 돌린다. 2분 30초. 돌아가는 소리를 들으며 휴대폰을 본다. 깃허브 알림을 다시 확인한다. "Closed" 표시가 있다. 정말 끝난 거다. 딩 소리가 난다. 도시락이 다 됐다. 먹으면서 생각한다. "다음 PR은 좀 더 잘해야지." 근데 다음 PR도 비슷할 것 같다. 댓글 받고, 구글링하고, 반만 이해하고, "감사합니다" 누르고. 그래도 괜찮다. 이게 배우는 거니까. 선배들도 다 이랬을 거니까. 그렇게 믿기로 한다. 퇴근 전 한 가지 더 퇴근 30분 전이다. 노션을 연다. "오늘 배운 것" 페이지다. 마지막 작성일이 2주 전이다. 다시 시작한다. "2024.01.15 배운 것:useCallback: 함수를 메모이제이션함 (아직 정확히는 모름) early return: 조건문을 먼저 처리하는 패턴 코드리뷰 답변 잘하는 법: 일단 감사하다고 하기"마지막 줄은 농담이다. 근데 사실이기도 하다. 저장한다. 노션 페이지를 닫는다. 슬랙을 확인한다. 새 메시지는 없다. 다행이다. 9시가 됐다. 가방을 챙긴다. 노트북을 넣는다. 무겁다. 엘리베이터를 탄다. 1층 버튼을 누른다. 내려가면서 생각한다. "내일은 새 이슈를 받을 거다. 또 PR을 올릴 거다. 또 리뷰를 받을 거다." "또 '감사합니다'를 누를 거다." 문이 열린다. 밖으로 나간다. 바람이 차다. 집에 가서 useCallback 강의를 봐야지. 진짜로 이해하고 싶다. 근데 아마 10분 보다가 잘 거다. 언제나 그랬듯이. 그래도 괜찮다. 조금씩이라도 배우고 있으니까. '감사합니다' 버튼을 누를 때마다, 진짜로 배우는 중이니까.오늘도 '감사합니다'를 7번 눌렀다. 내일은 몇 번 누를까.
- 12 Dec, 2025
동기들과의 퇴근 후 맥주: '너네 회사 어때'
동기들과의 퇴근 후 맥주: '너네 회사 어때' 목요일 저녁 8시 회사 앞 이자카야. 동기 셋이 왔다. 나까지 넷. "야 오랜만이다." 사실 한 달 전에 봤다. 테이블에 앉자마자 누가 먼저랄 것도 없이 맥주 4잔 시켰다. 생맥주 4천원. 회사 근처라 비싸다.첫 잔 받자마자 준호가 말했다. "아 진짜 오늘 개빡쳤다." 시작됐다. 다들 힘들대 준호는 스타트업 다닌다. 프론트엔드 혼자래. 디자이너도 없대. "피그마 파일 받았는데 그냥 와이어프레임이야. 이게 디자인이냐고." "그래서?" "내가 색 다 정하고 버튼 다 만들었지." "...그럼 디자이너 너네?" "응. 나." 민수는 대기업 계열사 들어갔다. 부럽다고 했었다. 지금은 아니다. "우리 회사 jQuery 쓴다." "뭐?" "jQuery." "2024년에?" "레거시래. 건드리면 안 된대." 나는 웃었다. 민수는 안 웃었다.재희는 SI 갔다. 3개월에 한 번씩 프로젝트 바뀐대. 지금은 관공서 시스템 만든대. "어제 고객사 가서 IE 11 테스트했다." "IE?" "응. 아직도 쓴대." "미쳤네." "나도 그렇게 생각해." 치킨 나왔다. 다들 먹었다. 5분 동안 아무도 말 안 했다. 그냥 먹었다. '너네 회사 어때' 준호가 물었다. "너는 어때." 나? 나도 힘들지. "선배가 코드리뷰 10개 달았어." "오 꼼꼼하네." "근데 무슨 말인지 모르겠어." "..." "일단 수정했어. 뭘 수정한 건지도 모르고." 민수가 웃었다. "나도 그래." 재희가 고개 끄덕였다. "나도." 준호도 웃었다. "나도 사실 그래." 갑자기 분위기가 풀렸다. "아 진짜 모르는 게 너무 많아." 준호가 말했다. "CI/CD 구축하래. 뭔지도 모르는데." "나는 Redis 캐싱하래." 민수가 말했다. "그게 뭔데." "나는 SQL 최적화하래." 재희가 말했다. "인덱스가 뭔지도 모르는데." 나는 웃었다. "나는 useCallback 언제 쓰는지도 모르겠어." 다들 웃었다.위로가 되는 이유 사실 해결책은 없다. 우리 중 누구도 답을 모른다. 그냥 다들 힘들다는 걸 확인했다. 그게 다다. 근데 이게 위로가 된다. 나만 못하는 게 아니구나. 다들 모르면서 일하는구나. 선배들도 처음엔 이랬겠지. 그런 생각. "근데 재밌을 때도 있지 않아?" 민수가 물었다. 준호가 대답했다. "있지. 코드 돌아갈 때." "나는 배포 성공했을 때." 재희가 말했다. 나는? "에러 원인 찾았을 때?" 다들 고개 끄덕였다. 그 순간은 진짜 좋다. 3시간 동안 삽질하다가 원인 찾으면. 콘솔에 에러 안 뜰 때. 새로고침했는데 정상 작동할 때. 그때는 진짜. 개발자 한 보람 있다. 근데 그게 하루에 한 번 있을까 말까다. 단톡방은 활발하다 우리 넷 말고도 동기들 더 있다. 단톡방 인원 12명. 거기는 항상 누군가 하소연한다. "오늘 배포 롤백했다 ㅠ" "회의 3시간 했는데 결론 없음" "내일 발표인데 PPT 10장 남음" "아직도 회사임 ㅋㅋ" 그럼 누군가 답한다. "ㅋㅋㅋㅋ" "힘내" "나도" "우리 다 똑같네" 별거 아닌 대화다. 근데 이게 힘이 된다. 혼자 아닌 것 같아서. 회사에서는 혼자다. 선배들은 바쁘다. 동기는 없다. 물어볼 사람도 없다. 그냥 구글링하고. GPT한테 물어보고. 유튜브 보고. 혼자 해결한다. 근데 이 단톡방에서는. 다들 나랑 똑같이 허우적거린다는 걸 안다. 그게 위로다. 10시 반 맥주 3잔 더 마셨다. 치킨 다 먹었다. 계산은 각자 냈다. 1인당 2만원. "다음엔 언제 보지." "한 달 후?" "그때쯤 되면 또 한 명쯤 이직하겠네." 웃으면서 헤어졌다. 집 가는 지하철. 핸드폰 봤다. 단톡방에 준호가 썼다. "오늘 고마웠어 ㅋㅋ" 재희가 답했다. "나도" 민수가 답했다. "다들 힘내자" 나도 썼다. "ㅇㅇ 힘내"해결책은 없었다. 그냥 다들 힘들다는 걸 확인했다. 근데 그게 유일한 위로였다.
- 10 Dec, 2025
'이거 제가 해볼게요'라고 했다가 후회하는 시간
'이거 제가 해볼게요'라고 했다가 후회하는 시간 오늘도 또 그랬다 오전 10시. 팀 데일리 스크럼. 선배가 물었다. "이거 누가 할 수 있어?" 나는 손을 들었다. "제가 해볼게요." 선배가 웃었다. "오, 좋아. 그럼 신입아 부탁해." 회의 끝나고 자리로 돌아왔다. 노트북 앞에 앉았다. ...뭐라고 했더라. 메모를 봤다. "API 연동 후 상태관리 리팩토링." 리팩토링이 뭐지. 아니, 안다. 코드 정리하는 거다. 근데 어떻게? 손이 떨렸다. 키보드를 쳤다. 지웠다. 다시 쳤다. 오늘도 시작됐다. 후회의 시간.왜 자꾸 그러는지 모르겠다 생각해봤다. 내가 왜 이러나. 선배가 물으면 일단 "해볼게요"가 나온다. 입에서 자동으로. 할 수 있는지 없는지도 생각 안 한다. 그냥 나온다. 머릿속에서는 경보가 울린다. '너 이거 못 하는데?' '이거 모르잖아?' 근데 입은 먼저 움직인다. "제가 해볼게요." 왜일까. 아마도 이유는 두 가지다. 첫째, 잘 보이고 싶다. 신입이니까. 일 열심히 하는 사람으로 보이고 싶다. 무능해 보이고 싶지 않다. 둘째, 거절을 못 한다. "저 이거 못 해요" 이 말이 안 나온다. 못 한다고 하면 실망시킬 것 같다. 그래서 일단 받는다. 생각은 나중에. 결과는? 지금처럼 책상 앞에서 식은땀 흘린다. 3시간째다. 진도는 10%.실제로 무슨 일이 벌어지나 구체적으로 적어본다. 월요일 오전 선배: "이거 간단한데, 드롭다운 컴포넌트 만들어줄래? 재사용 가능하게." 나: "네, 해볼게요." 월요일 오후 검색: "react reusable dropdown component" 결과: 20개 탭 열림 코드: 복붙 → 에러 → 다시 복붙 → 또 에러 화요일 선배: "어떻게 돼가?" 나: "거의 다 됐어요." (거짓말) 실제 진행률: 30% 머릿속: 패닉 수요일 야근 시작. 9시까지. 코드는 동작한다. 근데 왜 동작하는지 모른다. 복붙의 승리. 목요일 PR 올림. 심장이 두근거린다. 선배의 코멘트: "이 부분 useCallback 써야 할 것 같은데?" 나: useCallback이 뭐더라. 이게 반복이다. 매주. "제가 해볼게요" → 모르겠음 → 구글링 지옥 → 야근 → 동작은 하는데 이해는 못 함 → 코드리뷰 공포. 왜 이럴까. 왜 처음에 "저 이거 배우면서 해도 될까요?"라고 못 하나. 자존심? 아니다. 그냥 패턴이다. 나쁜 패턴. 최악의 순간들 기억나는 것들 적는다. 케이스 1: 테스트 코드 선배: "테스트 코드 좀 짜줄래?" 나: "네!" (테스트 코드를 한 번도 안 짜봤다) 결과: Jest 공식 문서 3시간 읽음 → 하나도 이해 못 함 → 결국 선배한테 "도와주세요" → 선배가 30분 만에 다 짜줌. 처음부터 모른다고 할 걸. 케이스 2: 타입 정의 선배: "이 API 응답 타입 정의해줄 수 있어?" 나: "할 수 있습니다!" (제네릭이 뭔지 모른다) 결과: 5시간 동안 any만 써서 완성 → 코드리뷰에서 "이거 타입 의미가 없는데요" → 선배가 다시 작성. 시간 낭비의 정석. 케이스 3: 성능 최적화 선배: "이 페이지 좀 느린 것 같은데, 최적화 좀 해볼래?" 나: "해보겠습니다!" (최적화를 해본 적이 없다) 결과: useMemo 막 갖다 붙임 → 더 느려짐 → 선배가 "뭐 한 거야" → 롤백. 민폐의 끝. 매번 이런다. 매번 후회한다. 근데 또 한다. 내가 이상한가.동기들도 그런가 궁금해서 물어봤다. 부트캠프 동기 단톡방에. "너네도 '해볼게요' 하고 후회해?" 답장이 왔다. 재민: "ㅋㅋㅋ 매일" 수진: "나 어제도 그랬음 ㅠㅠ" 민수: "형 그거 신입의 숙명임" 다들 그렇다. 재민이 보낸 메시지: "선배가 '이거 할 줄 알아?' 물으면 대답은 세 가지야.네 (거짓말) 네... (거의 거짓말) 아마도요 (완전 거짓말)"웃겼다. 근데 웃프다. 수진이 말했다. "나는 이제 '배우면서 해봐도 될까요?'라고 물어봐. 솔직하게." 현명하다. 나도 그래야 하는데. 민수는 달랐다. "형은 그냥 다 받아. 그래야 배워. 야근해도 돼." 극단적이다. 근데 이해는 된다. 결론: 다들 비슷하다. 신입은 다 이렇다. 위로가 됐다. 그래도 나만 이런 건 아니구나. 선배는 뭐라고 했나 용기 내서 물어봤다. 점심시간에 선배한테. "선배님, 제가 자꾸 '해볼게요' 하고 못 하는 것 같아요." 선배가 웃었다. "나도 그랬어." 진짜? "신입 때 무조건 다 받았지. 근데 반은 못 했어. 창피했어." 선배도 그랬다니. 신기하다. "그럼 어떻게 하셨어요?" "일단 받되, 바로 물어봐. '이거 어떻게 시작하면 되나요?' '이런 경우엔 어떻게 하나요?' 미리 물어보는 게 나중에 뒤집는 것보다 낫거든." 그렇구나. "그리고 진짜 모르는 건 솔직하게 말해. '저 이거 처음이라 시간 좀 걸릴 것 같은데 괜찮을까요?' 이렇게." 간단한데 왜 생각 못 했을까. "선배들도 다 알아. 신입이 뭘 모르는지. 티 안 내려고 해도 티 나거든. 차라리 솔직한 게 나아." 속이 시원했다. 선배가 말했다. "너무 자책하지 마. 배우는 단계야. 실수해도 돼." 고마웠다. 그날 오후부터 달라졌다. 모르는 거 바로 물었다. "이 부분 어떻게 하는 건지 모르겠어요." 선배가 5분 설명해줬다. 나는 2시간 삽질 안 했다. 효율적이다. 그래서 어떻게 할 건데 결론을 내려야 한다. 앞으로의 방침: 1. '해볼게요' 하기 전에 3초 생각한다진짜 할 수 있나? 얼마나 걸릴까? 도움이 필요한가?2. 조건부로 답한다"배우면서 해봐도 될까요?" "시간 좀 걸릴 것 같은데 괜찮으신가요?" "도중에 막히면 여쭤봐도 될까요?"3. 막히면 바로 물어본다2시간 삽질하지 않는다 30분 안 풀리면 슬랙 멘션 혼자 끙끙대는 게 민폐다4. 실패해도 괜찮다고 생각한다신입이니까 배우는 중이니까 완벽할 필요 없으니까이렇게 해보기로 했다. 며칠 지났다. 조금 나아졌다. 오늘 선배가 물었다. "이거 할 수 있어?" 나는 답했다. "해보고 싶은데요, 중간에 막히면 여쭤봐도 될까요?" 선배가 말했다. "그럼. 막히면 바로 물어봐." 마음이 편했다. 일은 절반 시간에 끝났다. 물어봤더니 쉬웠다. 왜 진작 이렇게 안 했을까. 마무리하며 여전히 "제가 해볼게요"라고 먼저 말한다. 근데 이제는 다르다. 할 수 있는지 먼저 생각한다. 조건을 단다. 도움을 요청한다. 후회는 줄었다. 야근도 줄었다. 스트레스도 줄었다. 완벽하진 않다. 가끔 또 옛날 버릇이 나온다. 일단 받고 나중에 패닉. 그래도 괜찮다. 배우는 중이니까. 신입이니까."해볼게요"와 "도와주세요" 사이의 적절한 균형, 그게 답이다.
- 04 Dec, 2025
에러 뜨면 일단 새로고침, 이게 최고의 디버깅 방법입니까
에러 뜨면 일단 새로고침, 이게 최고의 디버깅 방법입니까 아침부터 빨간 글씨 출근했다. 커피 마시고 컴퓨터 켰다. 어제 작업하던 코드 실행했다. 빨간 글씨가 뜬다. 일단 F5 눌렀다. 다시 빨간 글씨. F5 한 번 더. 또 빨간 글씨. 세 번째 새로고침 후에야 콘솔창을 봤다. "Cannot read property of undefined" 어쩌고. 무슨 말인지 모르겠다. 선배가 지나가다가 물었다. "뭐 안 돼?" "네... 에러가..." "콘솔 뭐라고 나와?" "아... 지금 보는 중이에요." 사실 방금 봤다. 세 번 새로고침 한 다음에.새로고침이 답인 줄 알았던 시절 부트캠프 때는 진짜 새로고침이 답이었다. 강사님이 말했다. "안 되면 새로고침 해보세요." 그래서 했다. 됐다. 신기했다. 개발서버 꺼졌을 때도 새로고침. 포트 번호 잘못 쳤을 때도 새로고침. 코드 저장 안 했을 때도 새로고침. 새로고침 3번이 안 되면 캐시 삭제. 그것도 안 되면 컴퓨터 재부팅. 이게 내 디버깅 프로세스였다. 입사 첫 주. 선배가 PR 코멘트 달았다. "이 부분 에러 핸들링 필요합니다." 무슨 말인지 몰랐다. 에러가 나면 새로고침 하면 되는 거 아닌가. 두 번째 주. 선배가 내 화면 보고 말했다. "새로고침 말고 콘솔 좀 보세요." 뜨끔했다. 들켰다. 콘솔은 무서운 곳 콘솔창을 열면 빨간 글씨가 가득하다. 숫자도 많다. :3742, :1849, :52. 뭔지 모른다. 줄번호라는 걸 3개월 차에 알았다. 에러 메시지는 영어다. 긴 영어다. 읽기 싫다. "Uncaught TypeError: Cannot read properties of undefined (reading 'map')" 읽어도 모른다. map이 뭐? undefined가 뭐? 다 아는 단어인데 합치니 모르겠다. 그래서 일단 새로고침 한다. 에러가 사라지면 좋겠다. 안 사라진다. 당연하다. 근데 매번 기대한다.3번의 법칙 내 디버깅 순서는 이렇다. 1번: 새로고침 2번: 새로고침 3번: 새로고침 4번: 콘솔 본다 왜 3번일까. 모른다. 그냥 3번은 해야 할 것 같다. 마법 같은 거다. 3번 하면 될 것 같은 기분. 선배가 물었다. "그거 왜 계속 새로고침 해요?" "아... 혹시 몰라서요." "혹시 뭐가요?" "그냥... 될까 봐서요." 선배가 한숨 쉬었다. 나도 안다. 이게 답이 아니라는 거. 근데 습관이다. 지금도 에러 뜨면 손이 먼저 간다. F5로. 생각보다 빠르다. 콘솔 읽는 것보다 빠르다. 새로고침이 진짜 답일 때 가끔은 진짜 새로고침이 답이다. 개발서버 재시작했을 때. 환경변수 바꿨을 때. 빌드 다시 했을 때. 이럴 땐 당당하다. "새로고침 하셔야 해요." 선배한테도 말한다. "캐시 문제일 수 있어요." 전문가 같다. 근데 대부분은 아니다. 새로고침이 답이 아닌 경우가 90%다. 아니, 95%다. 그래도 한다. 혹시 모르니까. 이번엔 5% 안에 들 수도 있으니까.에러 메시지를 읽기 시작한 날 3개월 차 어느 날이었다. 에러가 떴다. 새로고침 했다. 안 됐다. 또 했다. 안 됐다. 세 번째 했다. 여전히 안 됐다. 선배를 부를까 고민했다. 부끄러웠다. 또 새로고침만 했다고 혼날 것 같았다. 그래서 콘솝을 봤다. 천천히 읽었다. "data.map is not a function" data를 콘솔에 찍어봤다. console.log(data). 객체였다. 배열이 아니었다. 아. map은 배열에만 쓰는 거구나. 처음 알았다. 아니다, 알고는 있었다. 근데 까먹었다. 코드를 고쳤다. 됐다. 신기했다. 새로고침 안 하고 고쳤다. 뿌듯했다. 선배한테 말하고 싶었다. "저 혼자 해결했어요!" 근데 말 안 했다. 너무 당연한 걸 자랑하는 것 같아서. 여전히 새로고침부터 한다 그 뒤로도 나아졌을까. 아니다. 여전히 새로고침부터 한다. 지난주도 그랬다. API 호출이 안 됐다. 새로고침 했다. 안 됐다. 또 했다. 세 번째 후에 네트워크 탭을 봤다. 403 에러였다. 토큰이 만료됐다. 새로고침으로 해결될 리가 없다. 알고 있었다. 그래도 했다. 이게 습관이다. 나쁜 습관. 고쳐야 하는 습관. 근데 쉽지 않다. 선배가 말했다. "에러는 친구예요. 뭐가 잘못됐는지 알려주는 거예요." 맞는 말이다. 근데 친구가 빨간 글씨로 영어로 말하면 무섭다. 새로고침 카운터를 만들까 농담 반 진담 반으로 생각했다. 크롬 확장 프로그램. 새로고침 할 때마다 카운트. 하루에 몇 번 했는지 보여주기. "오늘 새로고침 237회. 그 중 의미 있었던 새로고침 2회." 부끄러울 것 같다. 근데 도움될 것 같다. 숫자로 보면 충격받을 것 같다. 동기한테 말했다. "나 새로고침 너무 많이 해." 걔도 그랬다. "나도. 습관임." 다들 그런가보다. 신입들은 다 그런가보다. 위안이 됐다. 근데 위안이 되면 안 되는데. 진짜 디버깅을 배우는 중 요즘은 조금 나아졌다. 에러 뜨면 일단 읽는다. 안 읽고 새로고침 하는 건 참는다. 손이 근질거려도 참는다. 콘솔에 console.log를 찍는다. 데이터가 어떻게 생겼는지 본다. undefined인지 null인지 빈 배열인지. 네트워크 탭도 본다. API 응답이 뭔지. 상태 코드가 뭔지. 200인지 400인지 500인지. 천천히 읽는다. 영어도 읽는다. 번역기 돌려서라도 읽는다. 시간이 오래 걸린다. 새로고침이 더 빠르다. 근데 새로고침은 답이 아니다. 알고 있다. 선배가 칭찬했다. "요즘 많이 늘었네요." 뭐가요? "에러 보고 물어보는 거. 예전엔 '안 돼요'였는데 요즘은 '이 에러가 이런데 이게 왜 이런 거죠?' 물어봐요." 기분 좋았다. 진짜로 늘은 건가. 아니면 그냥 새로고침 덜 하는 건가. 언제까지 이럴까 아직도 새로고침부터 할 때가 많다. 급할 때. 선배가 옆에 있을 때. 데모 직전일 때. 손이 먼저 간다. F5로. 고치고 싶다. 진짜 개발자는 이러면 안 될 것 같다. 에러를 읽어야 한다. 로그를 봐야 한다. 디버거를 써야 한다. 근데 쉽지 않다. 습관은 무섭다. 8개월 동안 만들어진 습관. 하루아침에 안 고쳐진다. 동기가 물었다. "너 요즘 어때?" "그냥... 살아있어. 근데 나 아직도 에러 나면 새로고침부터 해." "나도. 우리 언제 고쳐지려나." 모른다. 1년 차? 2년 차? 아니면 평생? 선배들도 새로고침 한다. 가끔. 진짜 필요할 때. 근데 그 '가끔'이 나랑 다르다. 나는 '항상'이니까. 그래도 나아지고 있다 3개월 전보다는 낫다. 새로고침 3번에서 2번으로 줄었다. 가끔은 1번만 하고 콘솔 본다. 가끔은 바로 콘솔 본다. 에러 메시지가 익숙해졌다. "Cannot read property" 나오면 undefined 체크 안 한 거다. "is not a function" 나오면 타입 확인해야 한다. 구글링도 늘었다. 에러 메시지 복사해서 검색한다. 스택오버플로우 답변 읽는다. 10개 중 1개는 도움된다. 선배한테 물어보는 것도 나아졌다. "안 돼요" 대신 "이 에러가 나는데 제가 이렇게 해봤는데도 안 되는데 혹시 뭐가 문제일까요?" 물어본다. 선배 표정이 달라졌다. 느리다. 진짜 느리다. 근데 나아지고는 있다. 신입에게 새로고침은 새로고침은 마법이 아니다. 알고 있다. 머리로는 안다. 근데 손은 모른다. 에러는 친구다. 무섭지만 친구다. 뭐가 잘못됐는지 알려주는 친구. 읽어야 한다. 천천히. 영어라도. 모르는 단어라도. 새로고침은 마지막이다. 콘솔 보고, 로그 찍고, 구글링하고, 그래도 안 되면. 그때 한 번. 이게 정답인 걸 안다. 근데 실천이 어렵다. 8개월 차 신입의 고백이다. 아직도 새로고침부터 한다. 부끄럽다. 근데 솔직하다. 언젠간 고쳐질까. 모르겠다. 그래도 오늘보다 내일이 나을 것 같다. 조금씩.오늘도 새로고침 57번. 어제보다 3번 줄었다. 진짜다.
- 02 Dec, 2025
useEffect 의존성 배열 7번 물어본 것 같은데 아직도 헷갈려요
useEffect 의존성 배열 7번 물어본 그 이야기 매일 아침이 반복된다. 슬랙을 킨다. 밤새 쌓인 메시지 5개. 심장이 철렁한다. 그중 3개는 선배 메시지다. 읽는다. 다행히 급한 건 아니다. 커피를 마신다. 따뜻하지만 손이 떨린다. 오늘도 useEffect 때문에 버그가 터졌다. 7번 물어본 그놈 정확히는 몇 번인지 모른다. 5번? 7번? 10번? 세기 싫다. 선배가 얼굴을 어떻게 봤는지가 기억난다. 첫 번째는 입사 3주차였다. "선배, 이거... useEffect가 계속 실행되는데 왜 그래요?" "의존성 배열을 제대로 안 넣었어." 그렇다. 그걸 모르니까 물어본 거다. 배열. 뭘 넣어야 하는데? 코드를 보여줬다. 선배가 수정했다. 이렇게 넣으면 된다고. 머리로는 이해했다. 그날은. 그다음 주 월요일. 또 틀렸다. "선배... 이번엔 뭐가 문제인가요?" "의존성 배열이..." 선배 목소리의 톤이 달라졌다. 같은 실수를 두 번 하면 안 되는 건데. 안 했다. 다른 실수를 했다. 더 복잡한. 근데 정말 모르겠다. 왜일까.간단한 게 간단하지 않은 날들 "의존성 배열? 그거 간단한 건데." 선배가 입사 2개월 차 신입들 앞에서 말했다. 나는 그 신입들 중 한 명이었다. 간단한 게 아니었다. 의존성 배열이 간단한 이유를 다시 생각해보자. 뭔가가 바뀌면 효과를 다시 실행한다. 그게 전부다. 근데 그게 뭔가가 정확히 뭔가? 배열에 넣은 것들? 객체면? 함수면? 배열 안의 배열이면? 변수 이름을 user라고 하자. 이건 의존한다. user가 바뀌면 함수가 다시 실행된다. 당연하다. 그런데 user.name이 바뀌면? user 객체 자체는 같은데? "그건 React가 못 감지한다." 맞다. 객체 동일성 비교(참조 비교)로 작동한다. 그래서 불변성이고... 어? 불변성? 또 다른 용어가 튀어나왔다. 용어는 계속 튀어나온다. 배웠다고 생각했는데 진짜 간단한 게 아니었다. 배열에 아무것도 안 넣으면? 매번 실행된다. 빈 배열을 넣으면? 한 번만 실행된다. 의존성을 넣으면? 그것만 감지한다. 이건... 세 가지다. 세 가지를 모두 알아야 한다. 근데 셋 다 외워졌다. 8개월 전에. 왜 자꾸 틀릴까. 안 보이는 함수들 코드를 다시 봤다. useEffect(() => { fetchUser(userId) }, [userId])fetchUser는 밖에 정의되어 있다. 함수다. 그럼 이 함수도 의존성에 넣어야 하는가? 아니다. 상수니까. 바뀌지 않으니까. 근데 만약 이 함수가 userId를 가지고 있으면? 그럼 간접 의존성인가? 잠깐. fetchUser 자체가 useCallback으로 감싸져 있으면? 의존성 배열이 또 하나 생긴다. 함수 안에. 그 안에도 배열이. 배열이 배열 안에. 머리가 복잡하다. 종이에 그려본다. useEffect └─ useCallback └─ useEffect? └─ 의존성 배열?모르겠다. 회의실을 나온다. 밖에는 햇빛이 있다. 근데 뇌는 어둡다.콘솔로 찍던 날 어제도 이렇게 했다. useEffect(() => { console.log("이펙트 실행됨 1") return () => { console.log("클린업됨 1") } }, [A])useEffect(() => { console.log("이펙트 실행됨 2") return () => { console.log("클린업됨 2") } }, [B])콘솔을 켠다. 실행 순서를 본다. 뭔가 순서가 이상하다. 왜 2번이 먼저 실행되지? 아, 렌더링 순서와 상관없이 의존성 배열을 봐야 한다. 근데 이게 바뀌는 건가 안 바뀌는 건가? 콘솔에 값을 직접 찍어본다. A의 값. {id: 1, name: "kim"}. 근데 이 객체가... 매번 새로 생성되는 건가? const obj = { id: userId }; useEffect(() => { // }, [obj])이러면 매번 실행된다. 객체는 매번 새로 만들어지니까. 참조가 다르니까. 알았다. 근데 왜 자꾸 까먹지? 점심시간에 같은 회사 동기 3명이 편의점에서 만났다. 삼각김밥을 먹고 있었다. "너희도 useEffect 때문에 스트레스 받아?" "받는데... 의존성 배열?" "응." "나도. 자꾸 까먹어." "근데 선배들한테 물어보기가..." 아무도 마저 말을 안 했다. 다 알고 있었다. 물어볼 때마다 선배 얼굴이 어떻게 보이는지. 입사 8개월에 여전히 기본을 못 하는 게 맞는지 아닌지. 삼각김밥을 다시 먹는다. 맛은 없다. 인강은 또 다시 퇴근 후 휴대폰을 킨다. 인프런 앱을 연다. "React 완벽 마스터 - useEffect 이해하기" 섹션. 시간: 47분. 플레이를 눌렀다가 멈춘다. 47분을 언제 봐? 밤 11시다. 내일 9시에 출근해야 한다. 최소 6시간은 자야 한다. "3분만 보자." 3분 지난 강사. "의존성 배열이 중요한 이유는..." 벌써 여기서? 15초 후에 댓글을 본다. "와 이 설명 최고" 44개의 좋아요. 나는 왜 이렇게 못 이해하지. 다음 화면. 예시 코드. 이건... 아까 본 건 같은데 다르다. 변수 이름이 다르고 로직이 다르다. 5분 지나니 졸린다. 강사는 계속 말한다. "...그래서 의존성 배열에..." 그 말을 마지막으로 들었다. 아주 마지막으로. 그다음 기억이 없다. 휴대폰을 잡은 건 자정이었다. 선배 눈치 코드 리뷰가 왔다. 3개 파일. 내가 쓴 코드. 빨간 줄. 첫 번째가 useEffect 부분이다. 댓글: "@이신입 의존성 배열 검토 필요" "네 수정하겠습니다." 아 이 말. 이 말을 너무 많이 한다. 수정하겠습니다. 할 수 있는 말 중 제일 무난하다. 모를 때. 뭔가 잘못됐을 때. 선배가 뭔가 지적할 때. "수정하겠습니다." 수정한다. 의존성 배열을 고치려고 한다. 근데 뭘 고쳐야 하는지 불명확하다. 선배가 뭘 원하는 건지? 일단 추측해본다. 아 이거 빼야겠네. 이거 추가해야겠네. 맞췄나? 아니면 내가 또 놓쳤나? 슬랙에 답장을 기다린다. 한 시간. 아무것도 안 온다. 더 기다린다. 2시간. "이것도 추가해 주세요." 또? 의존성 배열이 4줄이 된다. useEffect(() => { // }, [a, b, c, d])이렇게 많으면 뭔가 잘못된 것 같은데? 모르겠다.과거와 현재의 간격 8개월 전. 부트캠프 마지막 주. 강사가 useEffect를 설명했다. 의존성 배열도. 나는 이해했다. 정말 정말 이해했다. 프로젝트를 해봤다. 기본 요청에 useEffect 썼다. 동작했다. "난 할 수 있을 것 같은데." 면접장 앞. 합격 통지를 받고. "React 좀 할 줄 아세요?" "네." 그건 정말이었다. 그 시점에는. 근데 회사는 달랐다. 변수가 많다. 의존성이 얽혀 있다. 함수가 함수를 부른다. 컴포넌트가 컴포넌트 안에 있다. 의존성 배열 경고가 나온다. ESLint가 불평한다. "exhaustive-deps" 뭔가 의존성을 빠뜨렸다는 뜻이다. 근데 그걸 다 넣으면 무한 루프가 된다. 그럼? 메모이제이션. useCallback. useMemo. 또 다른 Hooks가 튀어나왔다. 각각의 의존성 배열도 있다. 하나를 배워서 정복했다고 생각했는데 또 다른 게 나타났다. 그리고 또. 못 할 게 아니라 배우는 중이라고 자위 오늘도 새벽 3시. 노션을 켠다. "오늘 배운 것"의존성 배열 클린업 함수 참조 비교 불변성? (확인 필요)3일 전에 쓴 글. "내일은 정리해서 블로그에 올려야지." 블로그에 올린 글은 없다. 정리할 시간이 없었다. 내일도 없을 것 같다. 근데 누군가는 이걸 처음 배울 때 얼마나 헷갈렸을까? 인터넷 구석에 보면 이런 글들이 있다. "useEffect 의존성 배열 초보자 가이드 - 5분만에 이해하기" 5분만에 이해하는 사람이 있나? 있는 것 같다. 유튜브 댓글에서 봤다. "오 이제 이해됐어요!" 그런 댓글을 남기는 사람들은 뭐가 다를까. 더 똑똑한 건가? 아니다. 그냥 처음부터 맞게 배웠을 뿐이다. 난 부트캠프에서 45분 짜리 영상으로 배웠다. 강사는 빠르게 설명했다. 그리고 지금 이렇다. 내일이면 또 누군가가 나한테 물어볼 수도 있다. "선배, useEffect가..." 아. 그건 아직 먼 것 같다. 여기는 내가 그 위치니까. 그래도 어제보다는 어제 정말 난처했던 코드가 있었다. useEffect(() => { if (data && data.length > 0) { setProcessed(true); } }, [data, setProcessed])근데 생각해보니 setProcessed는 상태 업데이트 함수니까 의존성에 안 넣어도 된다는 걸... 오늘 깨달았다. 작은 거지만 뭔가 알아낸 기분이다. 선배가 가르쳐준 게 아니다. 어제 PR 피드백에서 본 다른 사람의 코드. 거기서 봤다. "아 이렇게 쓰는 거구나." 0.1%의 이해도가 올라갔다. 8개월에 0.1%씩 올라가면... 800개월이면 100%다. 너무 오래다. 근데 다른 신입들도 비슷한 것 같다. 우리는 같은 속도로 나아가고 있다. 느리지만. 정확히 같은 속도로. 내일 회의에서 누군가 또 useEffect를 쓸 것 같다. 그럼 또 의존성 배열 얘기가 나올 거다. 그걸 들으면서 조금 더 알게 될 거다. 그게 배움이다. 반복이다. 선배한테 8번 물어봐도 좋다. 아니다. 12번 물어봐도 좋다. 그래도 된다. 아마도.다음 PR은 좀 나아지겠지. 같은 실수를 세 번 반복하면 못 하는 건가? 아니다. 여덟 번 반복할 수도 있다. 그리고 9번째에 맞추면 된다.