| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- 알고리즘
- 개발공부
- 자바
- 블로그
- JavaScript
- 개발일지
- 자바스크립트
- Java
- sourcetree
- 깃
- react
- 파이썬
- 소스트리
- 깃허브
- 블로그일기
- 프론트엔드
- 조회수
- Python
- 웹개발
- 리액트
- GIT
- 방문자수
- 정보처리기사
- 코딩테스트
- 개발자
- 프로그래밍
- Github
- IT정보
- IT기술
- 코딩
- Today
- Total
이롭게 현명하게
[E-LOG] React Hook "useEffect" is called conditionally. 본문

[목차]
오류 내용
원인
해결방법
[오류 내용]
<상황>
공공데이터포털에서 API를 사용해 데이터를 보여주는 프로젝트를 진행 중이었다.
API에서 제공하는 위치 데이터를 지도에 표시하는 과정에서 예외 처리를 시도하던 중 오류가 발생했다.
React Hook "useEffect" is called conditionally.
React Hooks must be called in the exact same order in every component render.
Did you accidentally call a React Hook after an early return?
[번역]
React Hook "useEffect"는 조건부로 호출됩니다.
React Hook은 모든 구성 요소 렌더링에서 정확히 동일한 순서로 호출되어야 합니다.
초기 복귀 후 실수로 React Hook을 호출하셨나요?
[원인]
<나의 코드>
import { useEffect } from "react";
import { Container as MapDiv, Marker, NaverMap, useNavermaps } from "react-naver-maps";
import "./index.css";
function MapBlock({ mapX, mapY }) {
const navermaps = useNavermaps();
if (!navermaps || !mapX || !mapY) {
return <p>위치를 표시할 수 없습니다.</p>;
}
useEffect(() => {
if (!navermaps || !mapX || !mapY) {
return <p>위치를 표시할 수 없습니다.</p>;
}
}, [navermaps, mapX, mapY]);
return (
<>
<MapDiv
style={{
width: "100%",
height: "600px",
}}
>
<NaverMap defaultCenter={new navermaps.LatLng(mapY, mapX)} defaultZoom={15}>
<Marker position={new navermaps.LatLng(mapY, mapX)} />
</NaverMap>
</MapDiv>
</>
);
}
export default MapBlock;
만약 mapX나 mapY의 값이 없어 지도에 표시를 못 한다면 <p> 위치를 표시할 수 없습니다. </p>를 반환했다.
그리고 그 아래에서 useEffect를 호출했다.
이때 문제가 되는 부분은 Hook 조건적으로 호출되었다는 것이다.
지금 보면 왜 이렇게 코드를 짠 건지 모르겠다.🥲
지도 좌푯값을 받아올 때 api에 없는 경우를 생각해서 if문으로 예외처리를 했다.
useEffect는... 왜... 저렇게 한 건지... ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
아마도 '이렇게도 가능하지 않을까?'라는 생각으로 작성한 거 같다.
<문제 원인>
useEffect가 조건문보다 아래에 있어서 ReactHook 규칙을 위반하였다.
if (!navermaps || !mapX || !mapY) {
return <p>위치를 표시할 수 없습니다.</p>;
}
useEffect(() => {
...
}, [navermaps, mapX, mapY]);
React에서 useEffect, useState 같은 hook은 항상 컴포넌트 함수의 최상단에서 호출되어야 한다.
렌더링마다 같은 순서로 호출되어야 한다.
내가 쓴 코드처럼 조건문에서 먼저 return을 해버리면 어떤 경우에는 useEffect가 호출되지 않는다.
<React Hook 규칙 >
- Hook은 항상 컴포넌트 최상단에서 호출되어야 한다.
- 조건문, 반복문, 함수 내에서 호출하면 안 된다.
- 이유 : 리액트는 렌더링마다 hook 호출순서를 기준으로 상태가 효과를 추적한다.
<useEffect안에서 JSX를 반환하면 안 되는 이유>
useEffect(() => {
if (!navermaps || !mapX || !mapY) {
return <p>위치를 표시할 수 없습니다.</p>; // ❌ 잘못된 사용
}
}, [navermaps, mapX, mapY]);
useEffect는 렌더링 결과를 반환하는 함수가 아니다.
부수 효과(side-effect)를 처리하기 위한 용도이다.
콘솔로그를 찍거나 데이터 요청, 상태 변경 등의 작업을 할 때 사용한다.
JSX를 반환해야 할 경우 return을 통해 렌더링 영역에서 처리해야 한다.
[해결 방법]
<올바른 방법>
- useEffect 내부는 JSX를 반환하면 안 된다.
- jsx를 반환하려면 return문 바깥에서 처리해야 한다.
- useEffect는 부수효과(side-Effect)를 수행하는 곳이다.
- ex: console.log, API 호출, 상태 업데이트 등
- Hook은 항상 컴포넌트 최상단에서 호출되어야 한다.
- 조건문, 반복문, 함수 내부에서 Hook을 호출하면 안 된다.
지도 api에서 useEffect를 넣어야 하는 건가? 아님 그냥 단순 조건문만 넣어줘도 되는 건가? → if문으로 처리하는 게 가장 좋다.
<수정한 코드>
import { Container as MapDiv, Marker, NaverMap, useNavermaps } from "react-naver-maps";
import BoxShadowCard from "../../../component/Card/BoxShadowCard";
import FlexBox from "../../../component/Layout/FlexBox";
import Space from "../../../component/Layout/Space";
import Text from "../../../component/Text/Text";
function MapSection({ mapX, mapY }) {
const navermaps = useNavermaps();
if (!navermaps || !mapX || !mapY) {
return (
<FlexBox>
<Text>위치를 표시할 수 없습니다.</Text>
</FlexBox>
);
}
return (
<>
<Text fontWeight="bold" fontSize="24px">
캠핑장 위치
</Text>
<Space height={3} />
<BoxShadowCard>
<MapDiv
style={{
width: "100%",
height: "600px",
}}
>
<NaverMap defaultCenter={new navermaps.LatLng(mapY, mapX)} defaultZoom={15}>
<Marker position={new navermaps.LatLng(mapY, mapX)} />
</NaverMap>
</MapDiv>
</BoxShadowCard>
</>
);
}
export default MapSection;
잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!☺️
댓글과 좋아요는 큰 힘이 됩니다!

'T-LOG > E-LOG' 카테고리의 다른 글
| [E-LOG] Vite 다운그레이드 중 ERESOLVE 의존성 충돌 오류 (0) | 2025.10.24 |
|---|---|
| [E-LOG] vite 환경 설정 오류 해결법 (0) | 2025.10.23 |
| [E-LOG] yarn create next-app@latest 오류 (0) | 2025.10.21 |
| [E-LOG] warning: img (0) | 2025.10.17 |
