I have created a todo list app I can add or remove elements in that list I am using react state for this purpose. Adding new element is perfectly working but removal isn't whenever I click on remove it just remove everything except the last item I have added I am using removeItem method to perform this functionality and I am filtering that clicked value and map rest of values in this function and I have tried to print those values in console ad well and I am getting desired output in console but those values are not getting stored in state array and I don't know why its happening:
import { useState } from 'react';
import './App.css';
let App = ()=>{
const [initial, addInitial] = useState('');
const [val, addVal] = useState([]);
let changeHandler = (e)=>{
addInitial(e.target.value)
}
let addItem =(event)=>{
let newItem = initial;
addVal( (prevValues) => [...prevValues, newItem]);
}
let removeItem = (par)=>{
val.map((value, index)=>{
if(index != par){
addVal([ [...value] ])
}else{
}
})
}
return(
<div id="parent">
<div id="container">
<h1>To-Do List</h1>
<div id="sub1">
<input type="text" value={initial} onChange ={changeHandler} placeholder='Add a item' autoFocus/>
<button id="add" onClick = {addItem}> </button>
</div>
<div id="sub2">
{
val.map((name, index)=>{
return(
<div id="cross" key={index}>
<button className="remove" id={index} onClick = { ()=> removeItem(index)}>❌</button>
{name}
</div>
)})
}
</div>
</div>
</div>
)
}
export default App;
CodePudding user response:
Instead of using map method just use filter method to filter out the removed item
let removeItem = (par)=>{
const arr = val.filter((item,index) => index != par)
addVal(arr)
}
CodePudding user response:
You can user array.splice to achieve your functionality:
let removeItem = (par) => {
const temp = [...val];
temp.splice(par, 1);
addVal([...temp]);
};
CodePudding user response:
Ok so it seems you are using "map" to remove item, instead you can use "filter" method.
const removeItem = (index)=>{
const filteredArray = val.filter((item, i) => i !== index)
addVal([...filteredArray])
}
The filter method remove all items that does not met the condition
CodePudding user response:
I updated you removeItem
function, you have to use filter instead of map
, could you please try this.
let removeItem = (par)=>{
const filter = val.filter((_, index) => index !== par);
addVal(filter)
}
CodePudding user response:
For just fixing your code, change removeItem
to this
let removeItem = (par)=>{
let newValues = [];
val.forEach((v, index) => {
if(index !== par){
newValues.push(v)
}
})
addVal(newValues)
}
A better way to rewrite the app would be
const App = ()=>{
const [todo, changeTodo] = useState('');
const [todos, addTodos] = useState([]);
const changeTodoTextHandler = (e)=>{
changeTodo(e.target.value)
}
const addTodo = ()=>{
addTodos([...todos, todo])
changeTodo('')
}
const removeTodo = (todoToDelete)=>{
const updatedTodos = todos.reduce((acc, current) => {
if(current !== todoToDelete) {
return [...acc, current]
}
return [...acc]
}, [])
addTodos(updatedTodos)
}
return(
<div id="parent">
<div id="container">
<h1>To-Do List</h1>
<div id="sub1">
<input type="text" value={todo} onChange ={changeTodoTextHandler} placeholder='Add a item' autoFocus/>
<button id="add" onClick = {addTodo}> </button>
</div>
<div id="sub2">
{
todos.map((todoName)=>{
return(
<div id="cross" key={todoName}>
<button className="remove" onClick = { ()=> removeTodo(todoName)}>❌</button>
{todoName}
</div>
)})
}
</div>
</div>
</div>
)
}