skip to Main Content

I know this is most common question but here i’m,
I’m creating the todo react app,i’ve just started using react but the thing is i’m already passing the id and then using as the key prop in the Todo Component,

i tried some of the solutions usally those works but this time i cannot understand even though i’m passing the id then using as the key
then why this error is occuring

import React from "react";
import Todo from "./todo";
const taskList = ({ items }) => {
    let itemsDisplay = [];

    if (items.length > 0) {

        itemsDisplay = items.map((todo, i) => {
            return <Todo id={i} todo={todo} />
        });
    }
    return (
        <>
            {itemsDisplay}
        </>
    )

}


export default taskList; 

this is my taskList which will receiver the list of task and those task are the array of objects

this is my todo component


import React from "react";
import './todo.css'
const Todo = ({ id, todo }) => {
    console.log(id, todo);
    return (
        <div style={{ display: "flex" }}>
            <li
                style={{
                    cursor: "pointer",
                    marginRight: "1rem"
                }}
                key={id}
                className={todo.complete ? "strike" : ""} >
                {todo.task}
            </li>

            <button  >
                Edit
            </button>
            <button >
                Delete buttn
            </button>
        </div>
    )
}

export default Todo;

3

Answers


  1. You have to provide a key attribute from React while you iterate not an id attribute:

     itemsDisplay = items.map((todo, i) => {
            return <Todo key={i} todo={todo} />
        });
    

    A quick tip:
    Always provide your key at the time of iteration (while you are iterating), in your case you are iterating with map() function, so this helps avoid confusion.

    From the child Todo, it doesn’t work in this case. React works like that.

    Login or Signup to reply.
  2. You have to put your key={id} on the `div´, so your todo component should look like this:

    import React from "react";
    import './todo.css'
    const Todo = ({ id, todo }) => {
        console.log(id, todo);
        return (
            <div style={{ display: "flex" }} key={id}>
                <li
                    style={{
                        cursor: "pointer",
                        marginRight: "1rem"
                    }}
                    className={todo.complete ? "strike" : ""} >
                    {todo.task}
                </li>
    
                <button  >
                    Edit
                </button>
                <button >
                    Delete buttn
                </button>
            </div>
        )
    }
    
    export default Todo;
    

    React uses the key prop create a relationship between the component and the DOM element. The library uses this relationship to determine whether or not the component should be re-rendered.

    Login or Signup to reply.
    1. Your component name should be in PascalCase. I would also suggest giving it name like Todos since it’s building a list of todos, and consistency is useful for debugging.

    2. There’s no need to create an empty array in the component. Presumably the data you’re passing in the component is an array so all you need to do is check if the array is empty. If it is return something to show there’s no data – otherwise use map to iterate over the array.

    3. Re the question: the key property should added during the map iteration process. It is not something that needs to be passed down to the component. It’s merely a way for React to better reconcile changes if you choose to reorder the list, for example.

    4. On that last point you shouldn’t be using the map index for the key value. Hopefully your todo objects will each have an id. If they don’t think about adding one. You can then use it as the key, and also as the mechanism by which todos can then be completed/deleted when you add that code.

    const { useState } = React;
    
    function Todos({ todos }) {
    
      if (!todos.length) return <div>Empty</div>;
    
      return (
        <section>
          {todos.map(todo => {
            return <Todo key={todo.id} todo={todo} />
          })}
        </section>
      );
    
    }
    
    function Todo({ todo }) {
      return (
        <div style={{ display: "flex" }}>
          <li
            style={{
              cursor: "pointer",
              marginRight: "1rem"
            }}
            className={todo.complete ? "strike" : ""}
          >{todo.task}
          </li>
          <button>Edit</button>
          <button>Delete</button>
        </div>
      );
    }
    
    const todos = [
      { id: 1, task: 'Write task 1', complete: false },
      { id: 2, task: 'Write task 2', complete: false },
      { id: 3, task: 'Write task 3', complete: false }
    ];
    
    const node = document.getElementById('root');
    const root = ReactDOM.createRoot(node);
    root.render(<Todos todos={todos} />);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.development.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.development.min.js"></script>
    <div id="root"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search