I have a handleAdd function that adds new components to an array of components, and I also have a handleDelete function that should remove the selected element from the array. I am generating unique keys for each element, but because of this the elements are not being deleted. Initially, the key was the index of the element in the array; deleting it was not done correctly; after the deleted element, the names disappeared.
import React, { useState, ReactElement } from "react";
import Category from "./components/Category";
import "./css/style.css";
function App() {
const [cardArray, setCardArray] = useState<ReactElement[]>([]);
const handleAdd = () => {
let key = Date.now() + Math.random();
setCardArray((prevArray: ReactElement[]) => [
...prevArray,
<Category key={key} onDelete={() => handleDelete(key)} />,
]);
};
const handleDelete = (index: number) => {
setCardArray((prevArray: ReactElement[]) =>
prevArray.filter((_, i) => i !== index)
);
};
return (
<div className="App">
<div className="categories">
<div className="categories-block">
<p>Categories</p>
</div>
<p className="plus" onClick={handleAdd}>
+
</p>
<p className="plus">-</p>
</div>
<div className="subcategories">
{cardArray.map((category, index) => (
<div key={index}>{category}</div>
))}
</div>
</div>
);
}
export default App;
2
Answers
The issue could be that using a combination of Date.now() and Math.random() for generating keys may result in non-unique and unstable keys. To fix this, it’s better to generate unique and stable keys for your elements by maintaining a separate key identifier for each element and using it consistently.
The expression Date.now() + Math.random() is not guaranteed to be unique because Date.now() returns the current timestamp in milliseconds, and Math.random() generates a random floating-point number between 0 (inclusive) and 1 (exclusive). If you generate keys in rapid succession, you might end up with the same key value.
Your code is anti-pattern of React. Please consider refactor your code. Try not to store ReactElement in state. React state is supposed to only store data rather than UI element.
E.g. you can store keys as array in cardArray, and then render from the array like:
cardArray.map((key) => (<Category key={key} onDelete={() => handleDelete(key)}>))
.Another issue is that the handleDelete is not dealing with keys but index, which is not matching how it’s used in onDelete.