\n
Deletes Last Created:
\n\n","author":{"@type":"Person","name":"Stove Games Games"},"upvoteCount":3,"answerCount":3,"acceptedAnswer":{"@type":"Answer","text":"I think the main problem is the key of items that you set as react doc says:
\n\n\nWhen you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:
\n
const todoItems = todos.map((todo, index) =>\n // Only do this if items have no stable IDs\n <li key={index}>\n {todo.text}\n </li>\n);\n
\n\n\nWe don’t recommend using indexes for keys if the order of items may\nchange. This can negatively impact performance and may cause issues\nwith component state. Check out Robin Pokorny’s article for an\nin-depth explanation on the negative impacts of using an index as a\nkey. If you choose not to assign an explicit key to list items then\nReact will default to using indexes as keys.
\n
As in this Article says:
\n\n\nReordering a list, or adding and removing items from a list can cause issues with the component state, when indexes are used as keys. If the key is an index, reordering an item changes it. Hence, the component state can get mixed up and may use the old key for a different component instance.
\nWhat are some exceptions where it is safe to use index as key?
\n
\n\n-If your list is static and will not change.
\n-The list will never be re-ordered.
\n-The list will not be filtered (adding/removing items from the list).
\n-There are no ids for the items in the list.
\n
If you set an reliable key in your items with some counter or id generator your problem would solve.
\nsomething like this:
\nexport default function App() {\n const [list, setList] = useState([]);\n const id = useRef({ counter: 0 });\n\n const AddInput = () => {\n console.log(id);\n setList([...list, { placeholder: "Class Name", id: id.current.counter++ }]);\n };\n\n const DeleteInput = (id) => {\n setList(list.filter((item, i) => item.id !== id));\n };\n\n const InputChangeHandler = (event, index) => {\n const l = [...list];\n l[index].value = event.target.value;\n setList(l);\n };\n\n return (\n <div>\n <button onClick={AddInput}>Add</button>\n {list.map((item, key) => (\n <div key={item.id}>\n <input\n type={"text"}\n id={key}\n placeholder={item.placeholder}\n onChange={(e) => InputChangeHandler(e, key)}\n />\n <button id={item.id} onClick={() => DeleteInput(item.id)}>\n Delete\n </button>\n </div>\n ))}\n </div>\n );\n}\n
\n","author":{"@type":"Person","name":"HDM91"},"upvoteCount":1}}}Reputation: 115
I'm having trouble deleting elements. Instead of deleting a specific element, it only deletes the last newly created element. I'm not sure where I'm going wrong here. I referenced this tutorial that shows what I kinda want to do. (I'm new to React)
import React,{useState, useRef} from "react";
const Body = () => {
const [list, setList] = useState([]);
const AddInput = () => {
setList([...list, {placeholder:"Class Name"}]);
};
const DeleteInput = (index) => {
const l = [...list];
l.splice(index,1);
setList(l);
};
const InputChangeHandler = (event, index) => {
const l = [...list];
(l[index]).value = event.target.value;
setList(l);
};
return (
<div>
<button onClick={AddInput}>Add</button>
{list.map((item, key)=>
<div key={key}>
<input type={"text"} id={key} placeholder={item.placeholder} onChange={e=>InputChangeHandler(e, key)}/>
<button id={key} onClick={() => DeleteInput(key)}>Delete</button>
</div>
)}
</div>
);
}
export default Body;
Element (input fields + button):
Deletes Last Created:
Upvotes: 3
Views: 84
Reputation: 1396
I think the main problem is the key of items that you set as react doc says:
When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort:
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
We don’t recommend using indexes for keys if the order of items may change. This can negatively impact performance and may cause issues with component state. Check out Robin Pokorny’s article for an in-depth explanation on the negative impacts of using an index as a key. If you choose not to assign an explicit key to list items then React will default to using indexes as keys.
As in this Article says:
Reordering a list, or adding and removing items from a list can cause issues with the component state, when indexes are used as keys. If the key is an index, reordering an item changes it. Hence, the component state can get mixed up and may use the old key for a different component instance.
What are some exceptions where it is safe to use index as key?
-If your list is static and will not change.
-The list will never be re-ordered.
-The list will not be filtered (adding/removing items from the list).
-There are no ids for the items in the list.
If you set an reliable key in your items with some counter or id generator your problem would solve.
something like this:
export default function App() {
const [list, setList] = useState([]);
const id = useRef({ counter: 0 });
const AddInput = () => {
console.log(id);
setList([...list, { placeholder: "Class Name", id: id.current.counter++ }]);
};
const DeleteInput = (id) => {
setList(list.filter((item, i) => item.id !== id));
};
const InputChangeHandler = (event, index) => {
const l = [...list];
l[index].value = event.target.value;
setList(l);
};
return (
<div>
<button onClick={AddInput}>Add</button>
{list.map((item, key) => (
<div key={item.id}>
<input
type={"text"}
id={key}
placeholder={item.placeholder}
onChange={(e) => InputChangeHandler(e, key)}
/>
<button id={item.id} onClick={() => DeleteInput(item.id)}>
Delete
</button>
</div>
))}
</div>
);
}
Upvotes: 1
Reputation: 21
Pass id to your DeleteInput function and for remove just filter the item list with id
const DeleteInput = (id) => {const filterItemList = list.filter((item) => item.id!== id);setList(filterItemList ); };
Upvotes: 0
Reputation: 147
Use filter.
const DeleteInput = (index) => {
const l = list.filter((_, i) => i !== index);
setList(l);
};
Upvotes: 0