Reputation:
I am trying to create a simple to do page using react after adding to do list item i am attaching trash icon & when user click its required its corresponding list item is deleted , i want to know if it can be done without using id, for ex in jquery it was simple (this.remove )
const [input, setValue] = useState("");
const [todos, setTodos] = useState([]);
// passing entered
const handleInput = (event) => {
setValue(event.target.value);
};
const lp = (event) => {
// let c = [1,2,34,55]
event.preventDefault();
// if no input nothing will happen return none
if (!input) return;
// using spread operator its used whenever we need to add array data to exiting array
const newTodos = [...todos, input];
setTodos(newTodos);
// clearing input text
setValue("");
};
const handeldel=(e) => {
// how to delete
}
return (
<div>
<div class="input-group mb-3">
<input
className="form-control border-primary font-weight-bold"
style={{ height: 60 }}
placeholder="Enter Text here"
type="text"
value={input}
onChange={handleInput}
/>
<div class="input-group-append">
<button
className="input-group-append font-weight-bolder "
style={{ fontSize: 20 }}
onClick={lp}
>
{" "}
<i class="fas fa-plus-square fa-2x p-2"></i>{" "}
</button>
</div>
</div>
{todos.map((x) => (
<ol style={{ listStyle: "none" }}>
<li className="font-weight-bolder table-bordered" style={{fontSize:20}}>
{x} <i class="fas fa-trash-alt" onClick={handeldel}></i>
</li>
</ol>
))}
</div>
);
};
Upvotes: 3
Views: 1174
Reputation: 170
As far as you're mapping an array to make a todos list there're a couple things you need to have in mind
// GOOD!!!
{todos.map(todo => (
<ol key={todo.uniqueKey} {...rest}>
...
</ol>
))}
// Don't do this, BAD!!!
{todos.map((todo, index) => (
<ol key={index} {...rest}>
...
</ol>
))}
Now, answering to your question, there's a simple way to do this, so i'll share with you the one i think is the best:
// Imagine you have these
const [todos, setTodos] = useState([
{ key: 'item1', content: 'some content' },
{ key: 'item2', content: 'some content' },
{ key: 'item3', content: 'some content' },
{ key: 'item4', content: 'some content' }
]);
// filter return a new array where the id is not like the one passed to handle del
// this is a function that returns a function
const handleDel = todoKey => e => setTodos(prev => prev.filter(todo => todo.key !== todoKey));
// Passing to the map you'll have something like
{todos.map(todo => (
<ol key={todo.key} style={{ listStyle: "none" }}>
<li className="font-weight-bolder table-bordered" style={{fontSize:20}}>
{todo.content} <i class="fas fa-trash-alt" onClick={handleDel(todo.key)}></i>
</li>
</ol>
))}
If using above approach then you have to modify your lp
and handleInput
functions, i'm giving you a simple example
// Here you're setting the unique key with Date.now()
// You're assigning an object to store what you need and save it later
// in your todos list
const handleInput = e => setValue({ key: new Date.now(), content: e.target.value });
const lp = (event) => {
event.preventDefault(); // as soon as it's not a submit button you don't need to preventDefault
if (!input) return;
// You can access to your previous state from inside your setState
// function, that's the same as you were doing but less verbose
setTodos(prevTodos => ([...prevTodos, input]));
// clearing input text
setValue({ key: null, content: '' });
};
// In your input you'll need to change to this as far as you're setting state with an object
<input
className="form-control border-primary font-weight-bold"
style={{ height: 60 }}
placeholder="Enter Text here"
type="text"
value={input.content} // <-- this is what you need to change
onChange={handleInput}
/>
// to not have problems with useState always initialize it with what you
// will need, in this example your input state will change to this
const [input, setValue] = useState({
key: null,
content: ''
});
I hope this helps you to understand more about react and how it works (also to teach some good techniques in case you didn't know 'em)
Upvotes: 0
Reputation: 7166
You can use an index
in order to delete the specific item
from the list
.
const handeldel = (index) => {
todos.splice(index, 1);
setTodos([...todos]);
}
And then HTML
{todos.map((x, index) => (
<ol style={{ listStyle: "none" }}>
<li className="font-weight-bolder table-bordered" style={{fontSize:20}}>
{x} <i class="fas fa-trash-alt" onClick={() => handeldel(index)}></i>
</li>
</ol>
))}
Upvotes: 1
Reputation: 601
const handeldel=(index) => {
todos.splice(index, 1);
}
todos.map((x, index) => (...
...
<i class="fas fa-trash-alt" onClick={(e)=>handeldel(index)}></i>
Upvotes: 1