Objects are not valid as a React child가 났을 때 무엇을 잘못 넣었는지 찾는 법
문제 발생
목록을 그리다가 화면이 죽고 이 오류가 났습니다.
Error: Objects are not valid as a React child (found: object with keys {name, email}).
If you meant to render a collection of children, use an array instead.원인 분석
React가 렌더할 수 있는 값은 정해져 있습니다 — 문자열, 숫자, React 엘리먼트, 그리고 그것들의 배열입니다. null·undefined·false는 아무것도 렌더하지 않고 넘어갑니다. 그 외의 일반 객체는 렌더 방법이 없어서 이 오류가 납니다.
다행히 메시지가 범인을 알려 줍니다. found: object with keys {name, email}처럼 그 객체의 키 목록이 함께 나오므로, 어떤 값을 그대로 넣었는지 특정할 수 있습니다.
흔한 경로는 이렇습니다.
- 객체를 통째로 넣음 —
{user}(의도는{user.name}) Date나BigInt같은 객체를 그대로 넣음- 오류 객체를 그대로 넣음 —
{error}(의도는{error.message}) - 컴포넌트를 호출하지 않고 넣음 —
{MyComponent}(의도는<MyComponent />) - 배열 대신 객체를 넣음 —
Object.entries를 잊고{map}
Promise를 넣으면 다른 메시지가 나지만 원인은 같은 부류입니다 — 렌더할 수 없는 값입니다.
해결 방안
- 메시지의 키 목록으로 값을 특정합니다.
{name, email}이 나왔다면 그 모양의 객체를 찾습니다. 여러 곳이면 React DevTools의 컴포넌트 트리에서 해당 컴포넌트를 짚습니다. - 필요한 필드를 꺼내 씁니다.
<p>{user}</p> {/* 오류 */}
<p>{user.name}</p> {/* 의도한 것 */}- 날짜는 문자열로 만듭니다.
Date는 객체입니다. 이 저장소는 화면용 한국어 형식과 기계용 ISO 문자열을 함께 제공합니다.
<time dateTime={date.toISOString()}>{formatDate(date)}</time>- 오류를 표시할 때는 메시지만 꺼냅니다.
{error && <p role="alert">{error.message}</p>}- 객체를 그대로 보여 줘야 하면 직렬화합니다. 디버깅 용도라면 이쪽이 편합니다.
<pre>{JSON.stringify(value, null, 2)}</pre>- TypeScript로 앞당겨 잡습니다.
ReactNode타입이 걸려 있으면 객체를 넣는 순간 컴파일 에러가 나므로, 이 오류를 런타임에서 만날 일이 크게 줄어듭니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.