I'm building a todo application in which all elements are inserted in a list of objects and then mapped using the map() function. I'm attempting to add a button with every map, that once clicked - will delete the specific element from the list. I've read quite a bit of documentation relating to the connection of useState and map(), but I'm still confused in how to implement this, and connect the specific element to the removal.
import { useState } from "react";
const List = (props) => {
return props.items.map((item) => {
return (
<>
<div>
<p>{item.item}</p>
<p>{item.date}</p>
<p>{item.id}</p>
</div>
{/* Below is the button im attempting to implement */}
<button onClick={}>Remove Item</button>
</>
);
});
};
export default List;
CodePudding user response:
The best way to understand this is by explaining an example.
Okay, so first we declare the array with the useState hook. I added some values just for example, but they are not needed.
The function add()
will create a new integer which will be the last integer of the array plus one, and then it will be added to the items array.
The function remove(item)
filters the items array by receiving an item as an argument and then filtering it with the filter()
JS method which removes all elements that do not pass the condition.
As you can see in the return Fragment the onClick
event handler passes the item parameter and then the remove()
function knows exactly which element to remove.
function List() {
const [items, setItems] = useState([0, 1, 2]);
const add = () => {
let newInt = items[items.length - 1] 1;
setItems([...items, newInt]);
};
const remove = (item) => {
let filteredArr = items.filter((el) => el !== item);
setItems(filteredArr);
};
return [
<Fragment>
<p>
<button onClick={() => add()}> Add Item</button>
</p>
{items.map((item, index) => {
return (
<p key={index}>
{item}
<button onClick={() => remove(item)}>x</button>
</p>
);
})}
</Fragment>
];
}
Note: I assume you know that import { useState } from "react";
and export default List;
are needed so I did not added to the code.
CodePudding user response:
As per your explanation, I kind of understand you have todo items and you need to remove an item by clicking the remove button so I have made one working demo to take dummy items and remove it, Kindly check the below code to remove items.
list.js
import React from 'react';
import { useState } from 'react';
const List = (props) => {
console.log(props);
const [items, setItems] = useState(props.items);
const remove = (item) => {
console.log(item);
let filteredArr = items.filter((el) => el.id !== item.id);
setItems(filteredArr);
};
const listItems = items.map((item, i) => (
<>
<div>
<p>{item.item}</p>
<p>{item.date}</p>
<p>{item.id}</p>
</div>
{/* Below is the button im attempting to implement */}
<button onClick={() => remove(item)}>Remove Item</button>
</>
));
return <div>{listItems}</div>;
};
export default List;
app.js
import React from 'react';
import './style.css';
import List from './lists.js';
export default function App() {
const items = [
{ id: 0, item: 'item 1', date: '22/12/2021' },
{ id: 1, item: 'item 2', date: '23/12/2021' },
{ id: 2, item: 'item 3', date: '24/12/2021' },
{ id: 3, item: 'item 4', date: '25/12/2021' },
];
return (
<>
<List items={items} />
</>
);
}
working demo link: https://stackblitz.com/edit/react-n4z2qj?file=src/App.js
CodePudding user response:
What you are looking for is .filter
which you can put in front of .map
. Furthermore you need a variable to keep track of the ids
that have been clicked/ deleted (if you don't want to actually remove them but instead just hide them).
const deletedItems = [1,2,3,4,5];
props.items
.filter(item => !deletedItems.includes(item.id))
.map(item => {
// ...
})