Showing Posts From

성장

에러 뜨면 일단 새로고침, 이게 최고의 디버깅 방법입니까

에러 뜨면 일단 새로고침, 이게 최고의 디버깅 방법입니까

에러 뜨면 일단 새로고침, 이게 최고의 디버깅 방법입니까 아침부터 빨간 글씨 출근했다. 커피 마시고 컴퓨터 켰다. 어제 작업하던 코드 실행했다. 빨간 글씨가 뜬다. 일단 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번 줄었다. 진짜다.

useEffect 의존성 배열 7번 물어본 것 같은데 아직도 헷갈려요

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번째에 맞추면 된다.