I am trying to make a todo app in which I made a functionality of delete when ever I delete a element , the element is deleted successfully but as soon as I type in input box I get this error.
Failed to execute ‘removeChild’ on ‘Node’: The node to be removed is not a child of this node.
import { React, useState } from 'react'
import "./todo.css"
function Todo() {
const [value, setValue] = useState("") //input value
const [items, setitems] = useState([]) //items to be added
function handleClick() {
// Adding items in a item array
setitems(items.concat(value))
setValue("")
}
function handleChange(e) {
// Fetching input value
setValue(e.target.value)
}
return (
<>
<div className='container'>
<h1 id='mainhead'>Todo App</h1>
</div>
<div className='container1'>
<input onChange={handleChange} value={value} placeholder='Enter a task' type="text" />
<button onClick={handleClick}>Add Item</button>
</div>
{/* mapping all the items */}
{items.length !== 0 ? items.map((e) => {
return <div className='item' key={e}><label>Task {items.indexOf(e) + 1}:</label> {e}
<button style={{float:"right" , backgroundColor:"red" , color:"white" , width:"80px" , height:"30px"}} onClick={()=>{
const child = document.getElementById("delete" + items.indexOf(e)) // accessing child
console.log(child)
child.parentElement.remove() //Deleting parent element
items.splice(items.indexOf(e),1) //removing element from items
setitems(items) // updating items
}} id = {"delete" + items.indexOf(e)}>Delete</button> </div>
})
: null}
</>
)
}
export default Todo
I tried everything but nothing works help me to handle this error
2
Answers
Instead of directly change the DOM, use the state to manage the items. To remove an item from the list, you can filter the item and set the new state.
Replace the onClick handler for the Delete button with the handleDelete() function. So the rendering will change this way:
BTW: The code above uses indexes for filtering and as a virtual DOM element key just to get as close as possible to your example. It’s a good practice to have unique IDs for elements. This can improve performance, help avoid errors, and make debugging easier.
You basically have all the bits you need for your component – most importantly the state that holds the todos. The necessary change is that the handler that is called when you click any of the delete buttons should simply
filter
out the right todo from the state.The best way to facilitate this is to ensure that the todos you add to the state are objects, and each object has an id. You then add that id to a data attribute so that when the handler is called you can use that id to filter the correct object from the state.
I’ve played around with your code a little – renamed things, and put the todos in a table – but hopefully the comments will help.