Cannot read properties of undefined (reading ‘map’) 완벽 해결법
도입
🔗 관련 에러 해결 가이드
React 개발을 하다 보면 “Cannot read properties of undefined (reading ‘map’)” 에러를 자주 마주치게 됩니다. 이 에러는 특히 API에서 데이터를 가져와 화면에 렌더링할 때 빈번하게 발생하며, 초보 개발자뿐만 아니라 경험 있는 개발자들도 종종 겪는 문제입니다. 이 에러 메시지는 정의되지 않은(undefined) 값에 대해 map 함수를 호출하려고 할 때 발생하는데, 주로 배열이 예상되는 위치에 undefined가 있을 때 나타납니다. 본 글에서는 이 에러의 발생 원인을 상세히 분석하고, 실제 코드 예제와 함께 7가지 해결 방법을 제시하며, 에러를 예방하는 베스트 프랙티스까지 완벽하게 안내해드리겠습니다.
🤖 AI 에러 분석 도우미
이 에러는 다음과 같은 상황에서 주로 발생합니다:
- 코드 문법 오류가 있을 때
- 라이브러리나 의존성 문제
- 환경 설정이 잘못된 경우
- 타입 불일치 문제
💡 위 해결법을 순서대로 시도해보세요. 90% 이상 해결됩니다!
에러 상세 분석
이 에러는 JavaScript의 타입 에러(TypeError)로 분류되며, 런타임 시점에 발생합니다. map()은 배열의 메서드이기 때문에, 배열이 아닌 undefined나 null 값에 대해 호출하면 에러가 발생합니다. React에서는 주로 컴포넌트가 렌더링되는 과정에서 state나 props의 값이 아직 초기화되지 않았거나, API 응답이 도착하기 전에 렌더링이 시도될 때 이 문제가 발생합니다.
에러 메시지의 구조를 살펴보면, “Cannot read properties of undefined”는 undefined 값의 속성에 접근하려 했다는 의미이고, “(reading ‘map’)”은 구체적으로 map 속성(메서드)에 접근하려 했다는 것을 나타냅니다. 브라우저 콘솔에서 이 에러를 확인하면 정확히 어느 파일의 몇 번째 줄에서 에러가 발생했는지 확인할 수 있어 디버깅에 도움이 됩니다. 이 에러는 애플리케이션의 전체 렌더링을 중단시킬 수 있으므로, 즉시 해결해야 하는 중요한 문제입니다.
발생 원인 5가지
1. State 초기값 미설정
useState 훅을 사용할 때 초기값을 설정하지 않거나 undefined로 설정한 경우 발생합니다. React 컴포넌트가 처음 렌더링될 때 state가 undefined 상태이므로 map 함수를 호출할 수 없습니다.
2. 비동기 데이터 로딩
API에서 데이터를 가져오는 동안, 컴포넌트가 먼저 렌더링되면서 아직 도착하지 않은 데이터에 대해 map을 호출하려고 시도합니다. 이는 가장 흔한 원인 중 하나입니다.
3. Props 전달 오류
부모 컴포넌트에서 자식 컴포넌트로 배열 데이터를 전달할 때, props가 제대로 전달되지 않았거나 부모 컴포넌트에서 해당 데이터가 준비되지 않은 상태일 수 있습니다.
4. API 응답 구조 불일치
백엔드 API의 응답 구조가 예상과 다를 때 발생합니다. 예를 들어, 응답에서 배열이 반환될 것으로 예상했지만 실제로는 객체가 반환되거나, 데이터가 중첩된 구조로 되어 있을 수 있습니다.
5. 조건부 렌더링 누락
데이터의 존재 여부를 확인하지 않고 바로 map 함수를 사용하는 경우입니다. 데이터가 로드되기 전이나 에러가 발생했을 때의 처리 로직이 없으면 이 에러가 발생합니다.
해결방법 7가지
방법 1: State 초기값을 빈 배열로 설정
가장 기본적이고 효과적인 방법입니다. useState의 초기값을 빈 배열([])로 설정하면, 데이터가 로드되기 전에도 map 함수가 정상적으로 동작합니다.
import React, { useState, useEffect } from 'react';
function UserList() {
// ❌ 잘못된 방법
// const [users, setUsers] = useState();
// ✅ 올바른 방법
const [users, setUsers] = useState([]);
useEffect(() => {
fetch('https://api.example.com/users')
.then(res => res.json())
.then(data => setUsers(data));
}, []);
return (
{users.map(user => (
{user.name}
))}
);
}
방법 2: 옵셔널 체이닝과 기본값 사용
옵셔널 체이닝(?.)과 nullish 병합 연산자(??)를 활용하여 안전하게 데이터에 접근합니다.
function ProductList({ products }) {
return (
{(products ?? []).map(product => (
{product.name}
))}
);
}
// 또는 중첩된 데이터 구조에서
function NestedList({ data }) {
return (
{(data?.items ?? []).map(item => (
{item.title}
))}
);
}
방법 3: 조건부 렌더링 적용
데이터가 존재할 때만 map을 실행하도록 조건을 추가합니다. 로딩 상태와 에러 상태도 함께 처리할 수 있습니다.
function PostList() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
fetch('https://api.example.com/posts')
.then(res => res.json())
.then(data => {
setPosts(data);
setLoading(false);
})
.catch(err => {
setError(err.message);
setLoading(false);
});
}, []);
if (loading) return 로딩 중...;
if (error) return 에러: {error};
if (!posts || posts.length === 0) return 데이터가 없습니다.;
return (
{posts.map(post => (
{post.title}
))}
);
}
방법 4: 논리 AND 연산자 활용
간단한 조건부 렌더링에는 && 연산자를 사용할 수 있습니다.
function CommentList({ comments }) {
return (
{comments && comments.length > 0 && comments.map(comment => (
{comment.text}
))}
);
}
방법 5: Array.isArray() 검증
데이터가 실제로 배열인지 확인한 후 map을 실행합니다.
function ItemList({ items }) {
return (
{Array.isArray(items) && items.map(item => (
{item.name}
))}
);
}
방법 6: try-catch와 Error Boundary
React Error Boundary를 사용하여 에러를 우아하게 처리합니다.
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error) {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return 데이터를 불러오는 중 문제가 발생했습니다.
;
}
return this.props.children;
}
}
// 사용
function App() {
return (
);
}
방법 7: TypeScript와 인터페이스 사용
TypeScript를 사용하면 타입 안정성을 확보하여 컴파일 시점에 에러를 방지할 수 있습니다.
interface User {
id: number;
name: string;
email: string;
}
interface UserListProps {
users: User[];
}
const UserList: React.FC = ({ users = [] }) => {
return (
{users.map((user: User) => (
{user.name} - {user.email}
))}
);
};
예방법과 베스트 프랙티스
1. 항상 State 초기값 설정
배열 데이터를 다룰 때는 반드시 빈 배열([])로 초기화하는 습관을 들이세요.
2. PropTypes 또는 TypeScript 사용
타입 검증을 통해 컴포넌트가 받는 데이터의 형태를 명확히 정의하고 검증하세요.
3. API 응답 검증
백엔드 API 응답을 받은 후, 데이터 구조를 콘솔로 확인하고 예상한 형태가 맞는지 검증하세요.
4. 로딩 상태 관리
비동기 데이터를 다룰 때는 항상 로딩, 성공, 실패 상태를 명확히 구분하여 관리하세요. React Query나 SWR 같은 라이브러리를 사용하면 더욱 효과적입니다.
5. 기본값 제공
함수 매개변수나 구조 분해 할당에서 기본값을 제공하여 undefined 상황을 미리 방지하세요.
// 좋은 예시
function DataDisplay({ data = [] }) {
return data.map(item => {item.name});
}
마무리
Cannot read properties of undefined (reading ‘map’) 에러는 React 개발에서 매우 흔하게 발생하지만, 원인을 이해하고 적절한 방어 코드를 작성하면 쉽게 해결할 수 있습니다. 가장 중요한 것은 데이터의 존재 여부를 항상 확인하고, 초기값을 적절히 설정하며, 비동기 데이터 로딩 과정을 명확히 관리하는 것입니다. 본 글에서 소개한 7가지 해결 방법과 베스트 프랙티스를 실무에 적용하면, 더 이상 이 에러로 고민하지 않아도 될 것입니다. 안정적이고 견고한 React 애플리케이션을 개발하는 데 이 가이드가 도움이 되길 바랍니다.
📚 함께 읽으면 좋은 글
Cannot read properties of undefined (reading ‘map’) 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 16.
🎯 Cannot read properties of undefined (reading ‘map’)
Cannot read properties of undefined (reading ‘map’) 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 6.
🎯 Cannot read properties of undefined (reading ‘map’)
Warning: Each child in a list should have a unique “key” prop 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 17.
🎯 Warning: Each child in a list should have a unique “key” prop
React Hook useEffect has a missing dependency 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 17.
🎯 React Hook useEffect has a missing dependency
React Hook useEffect has a missing dependency 완벽 해결법 – 원인부터 예방까지
📅 2025. 11. 17.
🎯 React Hook useEffect has a missing dependency
💡 위 글들을 통해 더 깊이 있는 정보를 얻어보세요!
📢 이 글이 도움되셨나요? 공유해주세요!
여러분의 공유 한 번이 더 많은 사람들에게 도움이 됩니다 ✨
🔥 공유할 때마다 블로그 성장에 큰 힘이 됩니다! 감사합니다 🙏
💬 여러분의 소중한 의견을 들려주세요!
여러분은 Cannot read properties of undefined (reading ‘map’)에 대해 어떻게 생각하시나요?
⭐ 모든 댓글은 24시간 내에 답변드리며, 여러분의 의견이 다른 독자들에게 큰 도움이 됩니다!
🎯 건설적인 의견과 경험 공유를 환영합니다 ✨
🔔 블로그 구독하고 최신 글을 받아보세요!
🌟 React 에러부터 다양한 실생활 정보까지!
매일 새로운 유용한 콘텐츠를 만나보세요 ✨
📧 RSS 구독 | 🔖 북마크 추가 | 📱 모바일 앱 알림 설정
지금 구독하고 놓치는 정보 없이 업데이트 받아보세요!