Showing Posts From
배열
- 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번째에 맞추면 된다.