ali
ali

Reputation: 147

why setItem aren't letting 'edit button' work?

i am trying to put a button of edit for each item with the help of simple hook. i have used map to see the elements of an item.... but somehow it's not working...while pressing the button nothing is showing..... Codesandbox link: https://codesandbox.io/s/condescending-worker-s0igh app.js:

import React, { useState } from "react";

import TodoList from "./TodoFiles/TodoList";

const defaultItems = [
  { id: 1, title: "Write React Todo Project", completed: true },
  { id: 2, title: "Upload it to github", completed: false }
];

const App = () => {
  const [items,setItems]=useState(defaultItems)

    const editItem=({id,title})=>{
      setItems(items.map(p=>p.id===id?{...p,title}:p))

    }
  return (
     <div style={{ width: 400 }}>
      <hr />
      <TodoList
        items={items}
        editItem={editItem}/>
      <hr />
    </div>
  );
};
export default App;

TodoList.js:

import React from "react";

const TodoItem = ({ title, completed, editItem }) => {

  return (

    <div style={{ width: 400, height: 25 }}>
      <input type="checkbox" checked={completed} />
      {title}

      <button style={{ float: "right" }} onClick={() => editItem(title)}>
        Edit
      </button>
    </div>
  );
};
const TodoList = ({ items = [], index,editItem }) => {


  return items.map((p, index) => (
    <TodoItem
      {...p}
      key={p.id}
      index={index}
      editItem={editItem}
    />
  ));
};

export default TodoList;

i don't want to use useEffect or useReducer fro custom hook ... because i want to practice with basics. sorry for my frequent questions, i'm trying so hard to learn this reactjs and i dun want to give up... thanx in advance and if it is possible, will you put some explanations in a plain text, why it's not working.

Upvotes: 1

Views: 69

Answers (1)

Legwan
Legwan

Reputation: 51

You forgot to pass id to editItem function on button onClick in TodoItem component.

Also you shouldn't use old state in setState function like that (in editItem function). You should use an updater function argument. Thanks to that you always modify current state.

const editItem = ({id,title}) => {
   setItems(oldItems => (olditems.map(p=>p.id===id?{...p,title}:p)))
}

import React from "react";

const TodoItem = ({id, title, completed, editItem }) => {

  return (

    <div style={{ width: 400, height: 25 }}>
      <input type="checkbox" checked={completed} />
      {title}

      <button style={{ float: "right" }} onClick={() => editItem({id,title})}>
        Edit
      </button>
    </div>
  );
};
const TodoList = ({ items = [], index,editItem }) => {


  return items.map((p, index) => (
    <TodoItem
      {...p}
      key={p.id}
      index={index}
      editItem={editItem}
    />
  ));
};

export default TodoList;

Upvotes: 1

Related Questions