728x90
반응형
문제 상황
함수 안에서 다음과 같이 코드를 작성 - "return { ...task, isEditting: true, ref: useRef<HTMLInputElement>() };"
.useRef
를 직접 map 내부에서 호출하면 에러가 남
1. 문제의 원인
1-1. React Hook 규칙 위반
- React의 공식 규칙(React Hooks 규칙, 공식문서)에 따르면,
Hook(예: useRef, useState, useEffect 등)은 컴포넌트 최상위(혹은 커스텀 Hook)에서만 호출해야 하며,
조건문, 반복문, 함수 내부 등에서 호출하면 안 됩니다. - master의 코드에서
처럼 map(반복문) 내부에서 useRef를 호출하면 "Invalid hook call" 에러가 발생합니다.prevList.map(task => { ... return { ...task, isEditting: true, ref: useRef<HTMLInputElement>() }; // <-- map 내부에서 Hook 호출 })
1-2. 공식 문서 근거
- React 공식 문서 - Rules of Hooks
"Only call Hooks at the top level. Don’t call Hooks inside loops, conditions, or nested functions."
- React 공식 문서 - useRef
"You can only call Hooks while React is rendering a function component or a custom Hook."
2. 해결한 수정사항
2-1. ref를 동적으로 할당하려면 createRef 사용
- createRef는 Hook이 아니므로 반복문/함수 내부에서 호출 가능합니다.
(React 공식문서 - createRef) - 따라서 아래처럼 수정해야 합니다.
// filepath: App.tsx
import { createRef } from 'react'; // createRef import 추가
// ...existing code...
return { ...task, isEditting: true, ref: createRef<HTMLInputElement>() }; // 수정: useRef → createRef
// ...existing code...
// 주석: createRef는 Hook이 아니므로 map 등 반복문 내부에서 호출해도 React 규칙에 위배되지 않습니다. (공식문서: https://react.dev/reference/react/createRef)
3. 찬성/반대 의견
- 찬성(createRef 사용):
- 반복문/함수 내부에서 안전하게 ref 객체를 생성할 수 있습니다.
- 공식 문서에서도 컴포넌트 외부나 반복문에서 ref가 필요할 때 createRef를 사용하라고 안내합니다.
- 반대(useRef 반복문 사용):
- React의 Hook 규칙을 위반하여, "Invalid hook call" 에러가 발생합니다.
- Hook의 호출 순서가 꼬여서 예측 불가능한 버그가 발생할 수 있습니다.
4. 추가 질문 및 토론 추천 키워드
- useRef와 createRef의 차이점과 각각의 사용 시점은 언제가 적절한가?
- React Hook 규칙을 위반했을 때 발생하는 실제 버그 사례와 그 영향
- 리스트 항목별로 ref를 안전하게 관리하는 패턴(예: Map, 배열, 커스텀 Hook 등)의 장단점
5. 결론
map 등 반복문 내부에서는 반드시 createRef를 사용해야 하며, useRef는 컴포넌트 최상위에서만 호출해야 합니다.
728x90
반응형
LIST
'문제해결' 카테고리의 다른 글
[vite/react/typescript] 프로젝트에 절대경로 적용하기 (1) | 2025.06.26 |
---|---|
[ollama web-ui] python 지원 버전 다를때 해결법 (3.13 vs 3.11) (0) | 2025.01.22 |