I wouldn't rely onto array length as it may change (items added and, what's worse, removed), so the simplest way would be to grab first unused id or maximum used id plus 1).
The latter would look as follows:
const addNumber = () => {
const ids = items.map(({id}) => id),
nextId = Math.max(...ids) + 1
setItems([
...items,
{
id: nextId,
value: input
}
])
}
The former, like this:
const addNumber = () => {
const ids = items.map(({id}) => id),
nextId = [...Array(x.length+1)]
.map((_,i) => i)
.find(n => !x.includes(n))
setItems([
...items,
{
id: nextId,
value: input
}
])
}
Following quick live-demo demonstrates the way of maintaining uniqueness of both record values and record id's:
const { useState } = React,
{ render } = ReactDOM,
rootNode = document.getElementById('root')
const App = () => {
const [items, setItems] = useState([]),
[errorMsg, setErrorMsg] = useState(),
onAddItem = e => {
e.preventDefault()
setErrorMsg(null)
const formData = new FormData(e.target),
value = formData.get('myInput'),
ids = items.map(({id}) => id),
nextId = [...Array(ids.length+1)]
.map((_,i) => i)
.find(n => !ids.includes(n))
if(items.some(({value:v}) => v == value)){
setErrorMsg('Value already exists')
} else {
setItems([
...items,
{
id: nextId,
value
}
])
e.target.reset()
}
},
onDeleteItem = _id =>
setItems(items.filter(({id}) => id !== _id))
return (
<div>
<form onSubmit={onAddItem}>
<input name="myInput" />
<input type="submit" value="Add Item" />
{errorMsg && <div className="errorMsg">{errorMsg}</div>}
</form>
{!!items.length &&
(
<ul>
{
items.map(({id, value}) => (
<li key={id}>
{value}
<span
onClick={() => onDeleteItem(id)}
className="removeButton"
>
❌
</span>
</li>
))
}
</ul>
)
}
</div>
)
}
render (
<App />,
rootNode
)
.removeButton {
font-size: 10px;
margin-left: 20px;
}
.removeButton:hover {
cursor: pointer
}
.errorMsg {
font-family: Arial;
font-size: 10px;
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>
Setdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Set, though, I would gladly support you to deploy my solutionSetwill work the best for primitive types, like strings or numbers but it won't help you to store more complex data (objects with multiple properties) which is usually the case