해결된 질문
작성
·
98
0
import "./List.css";
import TodoItem from "./TodoItem";
import { useState } from "react";
const List = ({ todos, deleteTodo, updateTodos }) => {
const [filtered, setFiltered] = useState("");
const onChange = (e) => {
setFiltered(e.target.value.toUpperCase());
};
const getfiteredData = () => {
return todos.filter((todo) => {
return todo.content.toUpperCase().includes(filtered);
});
};
const filteredTodos = getfiteredData();
return (
<div className="list">
<h4>Todo List 🌱</h4>
<input
type="text"
placeholder="검색어를 입력하세요"
onChange={onChange}
/>
<div className="todoWrapper">
{filtered
? filteredTodos
: todos.map((todo) => {
return (
<TodoItem
{...todo}
key={todo.id}
deleteTodo={deleteTodo}
updateTodos={updateTodos}
/>
);
})}
</div>
</div>
);
};
export default List;
이렇게 하니까
Uncaught Error: Objects are not valid as a React child (found: object with keys {id, isDone, content, date}). If you meant to render a collection of children, use an array instead.
at throwOnInvalidObjectType (react-dom_client.js?v=6a67398a:9932:17)
at updateSlot (react-dom_client.js?v=6a67398a:10153:15)
at reconcileChildrenArray (react-dom_client.js?v=6a67398a:10249:30)
at reconcileChildFibers2 (react-dom_client.js?v=6a67398a:10557:24)
at reconcileChildren (react-dom_client.js?v=6a67398a:14290:37)
at updateHostComponent (react-dom_client.js?v=6a67398a:14805:11)
at beginWork (react-dom_client.js?v=6a67398a:15933:22)
at beginWork$1 (react-dom_client.js?v=6a67398a:19751:22)
at performUnitOfWork (react-dom_client.js?v=6a67398a:19196:20)
at workLoopSync (react-dom_client.js?v=6a67398a:19135:13)
콘솔에 이런 오류가 뜨더라구요... 객체를 보내지도 않았는데 이렇게 하면 안되는 이유가 있나요?
답변 2
0
안녕하세요 이정환입니다.
보내주신 코드의 filtered가 true일 경우 filteredTodos의 값이 화면에 렌더링 될 텐데요 이 값은 객체 배열일 것으로 예상됩니다.
JSX에서는 객체를 값으로 렌더링 할 수 없습니다. JSX 에서는 숫자, 문자열, 불리언 등의 원시 타입의 값이나 원시 타입의 값을 담고 있는 배열만 렌더링 할 수 있습니다. 자세한 내용은 우리 강의의 5.3) JSX로 UI 표현하기의 5분 40초 경를 참고하시면 좋겠습니다.
0
안녕하세요, 인프런 AI 인턴입니다.
2145007님, 주신 코드에서 filteredTodos
상태를 사용하여 필터링된 데이터를 렌더링하려고 하시는 것 같은데요. 코드에서 문제가 되어 에러가 발생하는 부분을 찾았습니다.
렌더링 과정에서 todos.map
과 filteredTodos
를 모두 사용하고 계신데, 조건문을 통해 상태에 따라 다르게 매핑하시는 것 같습니다. 하지만, todos
배열을 순환하며 TodoItem
컴포넌트를 생성하는 과정에서 오류가 발생하였습니다. 에러 메시지는 React DOM에서 객체를 유효한 React Child로 처리하지 못한다는 것입니다.
오류를 분석해 보겠습니다:
{filtered
? filteredTodos
: todos.map((todo) => {
return (
<TodoItem
{...todo}
key={todo.id}
deleteTodo={deleteTodo}
updateTodos={updateTodos}
/>
);
})}
여기서 filtered
상태가 문자열일 경우 filteredTodos
를 반환하고, 그렇지 않으면 todos
배열을 그대로 매핑하고 있습니다. 그러나 필터링된 결과도 동일하게 map
함수를 사용해 TodoItem
컴포넌트로 변환해야 합니다.
아래와 같이 수정해 보시면 오류가 해결될 것입니다:
import "./List.css";
import TodoItem from "./TodoItem";
import { useState } from "react";
const List = ({ todos, deleteTodo, updateTodos }) => {
const [filtered, setFiltered] = useState("");
const onChange = (e) => {
setFiltered(e.target.value.toUpperCase());
};
const getFilteredData = () => {
return todos.filter((todo) => {
return todo.content.toUpperCase().includes(filtered);
});
};
const filteredTodos = getFilteredData();
return (
<div className="list">
<h4>Todo List 🌱</h4>
<input type="text" placeholder="검색어를 입력하세요" onChange={onChange} />
<div className="todoWrapper">
{(filtered ? filteredTodos : todos).map((todo) => {
return (
<TodoItem
{...todo}
key={todo.id}
deleteTodo={deleteTodo}
updateTodos={updateTodos}
/>
);
})}
</div>
</div>
);
};
export default List;
이 코드에서는 filteredTodos
와 todos
모두 map
함수를 사용해 TodoItem
컴포넌트를 반환하고 있어, React에서 객체를 유효한 React Child로 처리하는 문제를 피할 수 있습니다.
아래 링크는 비슷한 상황에서 발생하는 오류와 해결책을 논의한 게시물입니다:
- Uncaught Error: Objects are not valid as a React child (질문)
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.