Actualmente recibo el siguiente error en el componente Todos dentro TodoApp.tsx : 'Todos' no se puede usar como un componente JSX. Su tipo de retorno 'Element[]' no es un elemento JSX válido. Al tipo 'Elemento[]' le faltan las siguientes propiedades del tipo 'Elemento': tipo, accesorios, clave
Y esta es mi estructura de carpetas
TodoApp.tsx
function TodoApp() { return ( <Body> <AppDiv> <Form /> <Todos /> <Footer /> </AppDiv> </Body> ); } Todos.tsx
function Todos(): JSX.Element[] { const todos = useSelector((state: RootState) => state.todos); const footer = useSelector((state: RootState) => state.footer); if (footer.hideAll) { if (footer.showCompleted) { return todos .filter((todo) => !todo.completed) .map((todo: any) => ( <> <ul> <Todo todo={todo} /> </ul> </> )); } return todos.map((todo) => ( <> <div> <Todo todo={todo} /> </div> </> )); } return todos.map(() => ( <> <div></div> </> )); } Todo.tsx
type Todo = { todo: TodoProps; }; const Todo = ({ todo }: Todo) : JSX.Element => { const [isEditing, edit] = useState<boolean>(false); const dispatch = useDispatch(); if (!isEditing) { return ( <TodoDiv> <Li key={todo.id} completed={todo.completed} onClick={() => dispatch(completeTodo(todo.id))} // style={{ // textDecoration: todo.completed ? "line-through" : "none" // }} > {todo.text} </Li> <TodoBttns> <Button edit onClick={() => edit(!isEditing)}> <img src={editBttn} alt="Edit Button" /> </Button> <Button delete onClick={() => dispatch(deleteTodo(todo.id))}> <img src={deleteBttn} alt="Delete Button" /> </Button> </TodoBttns> </TodoDiv> ); } else { return ( <FormEdit> <InputForm key={todo.id} {...{ todo, edit }} /> </FormEdit> ); } };y la interfaz de TodoProps es la siguiente:
interface TodoProps { text: string; completed: boolean; id: string; } Ya probé la solución de envolver los elementos del mapa con fragmentos, pero todavía no puedo hacer que funcione. Lo único que a partir de ahora está solucionando el problema es declarar en la parte superior de Todos.tsx como esta function Todos(): any
Como nota al margen: estoy usando componentes con estilo, pero no creo que el problema esté relacionado con la biblioteca.
Un componente necesita devolver un único elemento raíz. Puede usar fragmentos para empaquetar una matriz de elementos como un solo elemento, usando el fragmento como ese único elemento raíz.
Así que esto no hace nada:
function Todos(): JSX.Element { return todos.map(todo => ( <> <li>{todo.task}</li> </> ) } Porque ahora está devolviendo una matriz de [<><li/></>, <><li/></>, ...] . Ese fragmento debe ser el único elemento raíz.
Necesitas usar el fragmento así:
function Todos(): JSX.Element { return <>{ todos.map(todo => <li>{todo.task}</li>) }</> }Anida todos los JSX devueltos en un solo fragmento.
Usando ese patrón, puede terminar con algo como esto:
function Todos(): JSX.Element { const todos = useSelector((state: RootState) => state.todos); const footer = useSelector((state: RootState) => state.footer); if (footer.hideAll) { if (footer.showCompleted) { return <>{ todos .filter((todo) => !todo.completed) .map((todo: any) => ( <ul> <Todo todo={todo} /> </ul> )) }</> } return <>{ todos.map((todo) => ( <div> <Todo todo={todo} /> </div> )) }</> } return <>{ todos.map(() => ( <div></div> )) }</> } // Works without error <Todos /> Tenga en cuenta cómo cada declaración de devolución devuelve solo un JSX.Element : el fragmento.
Debe devolver un elemento JSX, no una matriz. Envolver todo el componente es una solución, pero debe hacerlo fuera de la función de mapa/filtro.
Todos.tsx function Todos(): JSX.Element { const todos = useSelector((state: RootState) => state.todos); const footer = useSelector((state: RootState) => state.footer); if (footer.hideAll) { if (footer.showCompleted) { return ( <> {todos.filter((todo) => !todo.completed).map((todo: any) => ( <ul> <Todo todo={todo} /> </ul> )); } </> } return ( <> {todos.map((todo) => ( <div> <Todo todo={todo} /> </div> )); } </> } return ( <>{todos.map(() => <div />)}</> ); }En mi caso, fue una importación olvidada. Básicamente copié y pegué parte de mi código y olvidé importar uno de los componentes y este fue el mensaje de error que recibí.