C.W.K.
Stream
Lesson 05 of 05 · published

callback ref 로 측정해

~12 min · react, callback-ref, resize-observer

Level 0식은 재
0 XP0/33 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"waveform 이 0 폭으로 렌더됐어. ref 가 틀린 게 아냐 — 언제 읽느냐의 타이밍이 틀렸어."

버그: 0 폭 waveform

waveform 은 그리려면 컨테이너의 픽셀 폭을 알아야 해. 뻔한 React 수는 ref + 빈 의존성 배열의 mount-시점 useEffect 야: mount 때 ref.current.offsetWidth 를 읽어 폭을 세팅. 0 으로 렌더됐어. 이유가 미묘하고 체화할 가치가 있어: 타깃이 조건부 렌더면(트랙이 로드된 뒤에야 나타남), mount-시점 effect 가 요소가 아직 없을 때 돌아. effect 가 null ref 를 읽고 폭을 0 으로 세팅하고 — 의존성 배열이 비어서 — 스스로 고치러 다시 안 돌아.

수정: callback ref

callback ref 는 노드가 붙을 때 그리고 떨어질 때 React 가 부르는 함수야. 측정을 그 안에 넣으면, 정확히 맞는 순간 — 요소가 실제로 존재할 때 — 에 발화해, 너무 일찍 일어난 mount 가 아니라. 지속되는 크기 변경엔 그 같은 callback 안에서 ResizeObserver 를 붙여. 경험칙: mount-시점 useEffect 는 ref 가 이미 채워졌다고 가정해; 조건부거나 늦게 나타나는 것엔 attach 에 발화하는 callback ref 를 써.

자매 레슨: 검증된 코드를 다시 디버그하지 마

같은 엔진에 여기 짝지을 다른 종류의 scare 가 있었어. 세션 도중 소리가 멈춘 것 같았어. 본능은 scheduler 수학으로 다시 뛰어드는 거였는데 — 그 수학은 이미 차갑게 추적되고 검증됐어(하드웨어 신스를 박자 맞게 구동해). 진짜 원인은 reload 가 지운 transient state 였어; 깨진 코드가 없으니 코드 변경이 안 고쳤어. 규율: 검증된, 수학-맞는 코드가 모호한 증상으로 갑자기 '실패' 하면, 이미 증명한 부분을 다시 디버그하기 전에 transient state 를 먼저 의심해 — reload, 재현, 격리. 단단한 코드를 다시 의심하는 게 유령 쫓느라 오후를 태우는 방식이야.

Code

useEffect + ref 말고 callback ref 로 측정·typescript
// 틀림: mount-시점 effect 가 조건부 노드가 아직 null 일 때 돌아.
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
  setWidth(ref.current?.offsetWidth ?? 0);   // mount 때 ref.current === null
}, []);                                        // 다시 안 돎 -> 폭 0 유지

// 맞음: callback ref 가 노드 attach 때(그리고 detach 때) 발화.
const measureRef = useCallback((node: HTMLDivElement | null) => {
  if (!node) return;
  setWidth(node.offsetWidth);                  // attach 에 돎, 올바른 폭
  const ro = new ResizeObserver(() => setWidth(node.offsetWidth));
  ro.observe(node);                            // 리사이즈에도 올바르게 유지
}, []);
// 조건부거나 늦게 나타나는 것엔 measureRef 를 써.

External links

Exercise

UI 에서 mount 때 측정/초기화하는데 타깃이 아직 없을 수 있는 자리를 찾아(모달, 탭, 지연 로드 패널). 물어: 측정이 요소가 mount 때 있다고 가정해? 요소가 조건부로 나타나면 attach 에 발화하는 callback ref 로 다시 써 — 그리고 그 패턴이 '처음엔 0 으로 렌더돼' 버그를 얼마나 조용히 고치는지 봐.
Hint
냄새는 '리사이즈나 리렌더 후엔 되고, 첫 페인트엔 깨짐' 이야. 그게 아직 없던 요소의 mount-시점 읽기야. callback ref 는 요소가 있을 때 발화해서, 첫 페인트도 올발라.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 피파warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.