0

Here's my error that I got in my console:

Uncaught Error: Objects are not valid as a React child (found: object with keys {text, complete}). If you meant to render a collection of children, use an array instead.

This is my code below:

import React, { Fragment, useState } from "react";
import ReactDOM from "react-dom";

type FormElement = React.FormEvent<HTMLFormElement>;

interface ITodo {
  text: string;
  complete: boolean;
}

export default function App(): JSX.Element {
  const [value, setValue] = useState<string>("");
  const [todos, setTodos] = useState<ITodo[]>([]);

  const addTodo = (text: string) => {
    const newTodos: ITodo[] = [...todos, { text, complete: false }];
    setTodos(newTodos);
  };

  const handleSubmit = (e: FormElement): void => {
    e.preventDefault();
    addTodo(value);
    setValue("");
  };

  return (
    <Fragment>
      <h1>Todo List</h1>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          value={value}
          onChange={(e) => setValue(e.target.value)}
          required
        />
        <button type="submit">Add Todo</button>
      </form>
      <div>
        {todos.map((todo: ITodo, index: number) => (
          <div key={index}>{todo}</div>
        ))}
      </div>
    </Fragment>
  );
}

const root = document.getElementById("app-root");
ReactDOM.render(<App />, root);

At first I thought there was a problem with my map but then I couldn't see any problem with it. Any idea what did I miss in the code? It's pretty simple todo list app which at the moment the functionality is adding a todo and displays it on the screen underneath the input.

2
  • <div key={index}>{todo}</div>: todo is an object according to its interface. This isn't allowed (like the error says). If you're trying to print the text change it to {todo.text}. Commented Jun 9, 2020 at 16:48
  • @BrianThompson yes! Oh dear, silly mistake Commented Jun 9, 2020 at 16:49

1 Answer 1

1

You likely want to change from

<div key={index}>{todo}</div>

to

<div key={index}>{todo.text}</div> or <div key={index}>{todo.complete}</div>

inside your todos.map function, as todo is an object that cannot be rendered by React naturally.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.